QP is an event-driven, RTOS-like, active object framework for microcontrollers, such as mbed. The QP framework provides thread-safe execution of active objects (concurrent state machines) and support both manual and automatic coding of UML statecharts in readable, production-quality C or C++. Automatic code generation of QP code is supported by the free QM modeling tool.

Dependents:   qp_hangman qp_dpp qp_blinky

QP/C++ (Quantum Platform in C++) is a lightweight, open source active object (actor) framework for building responsive and modular real-time embedded applications as systems of asynchronous event-driven active objects (actors). The QP/C++ framework is a member of a larger family consisting of QP/C++, QP/C, and QP-nano frameworks, which are all strictly quality controlled, thoroughly documented, and available under GPLv3 with a special Exception for mbed (see http://www.state-machine.com/licensing/QP-mbed_GPL_Exception.txt).

The behavior of active objects is specified in QP/C++ by means of hierarchical state machines (UML statecharts). The framework supports manual coding of UML state machines in C++ as well as automatic code generation by means of the free QM modeling tool (http://www.state-machine.com/qm).

Please see the "QP/C++ Reference Manual" (http://www.state-machine.com/qpcpp) for more information.

Revision:
9:ca2e6010d9e2
Parent:
7:bf92d3a6625e
--- a/qp.cpp	Mon Sep 26 03:27:09 2011 +0000
+++ b/qp.cpp	Tue Sep 04 22:20:52 2012 +0000
@@ -1,2196 +1,2778 @@
-//////////////////////////////////////////////////////////////////////////////
-// Product: QP/C++, selectabel Vanilla/QK kernels
-// Last Updated for QP ver: 4.2.04 (modified to fit in one file)
-// Date of the Last Update: Sep 25, 2011
-//
-//                    Q u a n t u m     L e a P s
-//                    ---------------------------
-//                    innovating embedded systems
-//
-// Copyright (C) 2002-2011 Quantum Leaps, LLC. All rights reserved.
-//
-// This software may be distributed and modified under the terms of the GNU
-// General Public License version 2 (GPL) as published by the Free Software
-// Foundation and appearing in the file GPL.TXT included in the packaging of
-// this file. Please note that GPL Section 2[b] requires that all works based
-// on this software must also be made publicly available under the terms of
-// the GPL ("Copyleft").
-//
-// Alternatively, this software may be distributed and modified under the
-// terms of Quantum Leaps commercial licenses, which expressly supersede
-// the GPL and are specifically designed for licensees interested in
-// retaining the proprietary status of their code.
-//
-// Contact information:
-// Quantum Leaps Web site:  http://www.quantum-leaps.com
-// e-mail:                  info@quantum-leaps.com
-//////////////////////////////////////////////////////////////////////////////
-#include "qp_port.h"                                                // QP port
-
-#ifdef Q_USE_NAMESPACE
-namespace QP {
-#endif
-
-Q_DEFINE_THIS_MODULE(qp)
-
-// "qep_pkg.h" ===============================================================
-/// internal QEP constants
-enum QEPConst {
-    QEP_EMPTY_SIG_ = 0,                ///< empty signal for internal use only
-
-    /// maximum depth of state nesting (including the top level), must be >= 3
-    QEP_MAX_NEST_DEPTH_ = 6
-};
-
-/// helper macro to trigger internal event in an HSM
-#define QEP_TRIG_(state_, sig_) \
-    ((*(state_))(this, &QEP_reservedEvt_[sig_]))
-
-/// helper macro to trigger exit action in an HSM
-#define QEP_EXIT_(state_) \
-    if (QEP_TRIG_(state_, Q_EXIT_SIG) == Q_RET_HANDLED) { \
-        QS_BEGIN_(QS_QEP_STATE_EXIT, QS::smObj_, this) \
-            QS_OBJ_(this); \
-            QS_FUN_(state_); \
-        QS_END_() \
-    }
-
-/// helper macro to trigger entry action in an HSM
-#define QEP_ENTER_(state_) \
-    if (QEP_TRIG_(state_, Q_ENTRY_SIG) == Q_RET_HANDLED) { \
-        QS_BEGIN_(QS_QEP_STATE_ENTRY, QS::smObj_, this) \
-            QS_OBJ_(this); \
-            QS_FUN_(state_); \
-        QS_END_() \
-    }
-
-// "qep.cpp" =================================================================
-// Package-scope objects -----------------------------------------------------
-QEvent const QEP_reservedEvt_[] = {
-#ifdef Q_EVT_CTOR
-    (QSignal)QEP_EMPTY_SIG_,
-    (QSignal)Q_ENTRY_SIG,
-    (QSignal)Q_EXIT_SIG,
-    (QSignal)Q_INIT_SIG
-#else
-    {(QSignal)QEP_EMPTY_SIG_, (uint8_t)0, (uint8_t)0},
-    {(QSignal)Q_ENTRY_SIG,    (uint8_t)0, (uint8_t)0},
-    {(QSignal)Q_EXIT_SIG,     (uint8_t)0, (uint8_t)0},
-    {(QSignal)Q_INIT_SIG,     (uint8_t)0, (uint8_t)0}
-#endif
-};
-//............................................................................
-//lint -e970 -e971 -e778         ignore MISRA rules 13 and 14 in this function
-char const Q_ROM * Q_ROM_VAR QEP::getVersion(void) {
-    static char const Q_ROM Q_ROM_VAR version[] = {
-        (char)(((QP_VERSION >> 12U) & 0xFU) + (uint8_t)'0'),
-        '.',
-        (char)(((QP_VERSION >>  8U) & 0xFU) + (uint8_t)'0'),
-        '.',
-        (char)(((QP_VERSION >>  4U) & 0xFU) + (uint8_t)'0'),
-        (char)((QP_VERSION          & 0xFU) + (uint8_t)'0'),
-        '\0'
-    };
-    return version;
-}
-
-// "qhsm_top.cpp" ============================================================
-QState QHsm::top(QHsm *, QEvent const *) {
-    return Q_IGNORED();                    // the top state ignores all events
-}
-
-// "qhsm_ini.cpp" ============================================================
-QHsm::~QHsm() {
-}
-//............................................................................
-void QHsm::init(QEvent const *e) {
-    QStateHandler t;
-    QS_INT_LOCK_KEY_
-
-                              // the top-most initial transition must be taken
-    Q_ALLEGE((*m_state)(this, e) == Q_RET_TRAN);
-
-    t = (QStateHandler)&QHsm::top;              // HSM starts in the top state
-    do {                                           // drill into the target...
-        QStateHandler path[QEP_MAX_NEST_DEPTH_];
-        int8_t ip = (int8_t)0;                  // transition entry path index
-
-
-        QS_BEGIN_(QS_QEP_STATE_INIT, QS::smObj_, this)
-            QS_OBJ_(this);                        // this state machine object
-            QS_FUN_(t);                                    // the source state
-            QS_FUN_(m_state);          // the target of the initial transition
-        QS_END_()
-
-        path[0] = m_state;
-        (void)QEP_TRIG_(m_state, QEP_EMPTY_SIG_);
-        while (m_state != t) {
-            ++ip;
-            path[ip] = m_state;
-            (void)QEP_TRIG_(m_state, QEP_EMPTY_SIG_);
-        }
-        m_state = path[0];
-                                               // entry path must not overflow
-        Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_);
-
-        do {           // retrace the entry path in reverse (desired) order...
-            QEP_ENTER_(path[ip]);                            // enter path[ip]
-            --ip;
-        } while (ip >= (int8_t)0);
-
-        t = path[0];                   // current state becomes the new source
-    } while (QEP_TRIG_(t, Q_INIT_SIG) == Q_RET_TRAN);
-    m_state = t;
-
-    QS_BEGIN_(QS_QEP_INIT_TRAN, QS::smObj_, this)
-        QS_TIME_();                                              // time stamp
-        QS_OBJ_(this);                            // this state machine object
-        QS_FUN_(m_state);                              // the new active state
-    QS_END_()
-}
-
-// "qhsm_dis.cpp" ============================================================
-void QHsm::dispatch(QEvent const *e) {
-    QStateHandler path[QEP_MAX_NEST_DEPTH_];
-    QStateHandler s;
-    QStateHandler t;
-    QState r;
-    QS_INT_LOCK_KEY_
-
-    t = m_state;                                     // save the current state
-
-    QS_BEGIN_(QS_QEP_DISPATCH, QS::smObj_, this)
-        QS_TIME_();                                              // time stamp
-        QS_SIG_(e->sig);                            // the signal of the event
-        QS_OBJ_(this);                            // this state machine object
-        QS_FUN_(t);                                       // the current state
-    QS_END_()
-
-    do {                                // process the event hierarchically...
-        s = m_state;
-        r = (*s)(this, e);                           // invoke state handler s
-    } while (r == Q_RET_SUPER);
-
-    if (r == Q_RET_TRAN) {                                // transition taken?
-#ifdef Q_SPY
-        QStateHandler src = s;       // save the transition source for tracing
-#endif
-        int8_t ip = (int8_t)(-1);               // transition entry path index
-        int8_t iq;                       // helper transition entry path index
-
-        path[0] = m_state;                // save the target of the transition
-        path[1] = t;
-
-        while (t != s) {       // exit current state to transition source s...
-            if (QEP_TRIG_(t, Q_EXIT_SIG) == Q_RET_HANDLED) {   //exit handled?
-                QS_BEGIN_(QS_QEP_STATE_EXIT, QS::smObj_, this)
-                    QS_OBJ_(this);                // this state machine object
-                    QS_FUN_(t);                            // the exited state
-                QS_END_()
-
-                (void)QEP_TRIG_(t, QEP_EMPTY_SIG_);    // find superstate of t
-            }
-            t = m_state;                       // m_state holds the superstate
-        }
-
-        t = path[0];                               // target of the transition
-
-        if (s == t) {         // (a) check source==target (transition to self)
-            QEP_EXIT_(s)                                    // exit the source
-            ip = (int8_t)0;                                // enter the target
-        }
-        else {
-            (void)QEP_TRIG_(t, QEP_EMPTY_SIG_);        // superstate of target
-            t = m_state;
-            if (s == t) {                   // (b) check source==target->super
-                ip = (int8_t)0;                            // enter the target
-            }
-            else {
-                (void)QEP_TRIG_(s, QEP_EMPTY_SIG_);       // superstate of src
-                                     // (c) check source->super==target->super
-                if (m_state == t) {
-                    QEP_EXIT_(s)                            // exit the source
-                    ip = (int8_t)0;                        // enter the target
-                }
-                else {
-                                            // (d) check source->super==target
-                    if (m_state == path[0]) {
-                        QEP_EXIT_(s)                        // exit the source
-                    }
-                    else { // (e) check rest of source==target->super->super..
-                           // and store the entry path along the way
-                           //
-                        iq = (int8_t)0;         // indicate that LCA not found
-                        ip = (int8_t)1;     // enter target and its superstate
-                        path[1] = t;          // save the superstate of target
-                        t = m_state;                     // save source->super
-                                                  // find target->super->super
-                        r = QEP_TRIG_(path[1], QEP_EMPTY_SIG_);
-                        while (r == Q_RET_SUPER) {
-                            ++ip;
-                            path[ip] = m_state;        // store the entry path
-                            if (m_state == s) {           // is it the source?
-                                iq = (int8_t)1;     // indicate that LCA found
-                                               // entry path must not overflow
-                                Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_);
-                                --ip;               // do not enter the source
-                                r = Q_RET_HANDLED;       // terminate the loop
-                            }
-                            else {      // it is not the source, keep going up
-                                r = QEP_TRIG_(m_state, QEP_EMPTY_SIG_);
-                            }
-                        }
-                        if (iq == (int8_t)0) {       // the LCA not found yet?
-
-                                               // entry path must not overflow
-                            Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_);
-
-                            QEP_EXIT_(s)                   // exit the source
-
-                            // (f) check the rest of source->super
-                            //                  == target->super->super...
-                            //
-                            iq = ip;
-                            r = Q_RET_IGNORED;       // indicate LCA NOT found
-                            do {
-                                if (t == path[iq]) {       // is this the LCA?
-                                    r = Q_RET_HANDLED;   // indicate LCA found
-                                    ip = (int8_t)(iq - 1); // do not enter LCA
-                                    iq = (int8_t)(-1);   // terminate the loop
-                                }
-                                else {
-                                    --iq;    // try lower superstate of target
-                                }
-                            } while (iq >= (int8_t)0);
-
-                            if (r != Q_RET_HANDLED) {    // LCA not found yet?
-                                // (g) check each source->super->...
-                                // for each target->super...
-                                //
-                                r = Q_RET_IGNORED;             // keep looping
-                                do {
-                                                          // exit t unhandled?
-                                    if (QEP_TRIG_(t, Q_EXIT_SIG)
-                                        == Q_RET_HANDLED)
-                                    {
-                                        QS_BEGIN_(QS_QEP_STATE_EXIT,
-                                                  QS::smObj_, this)
-                                            QS_OBJ_(this);
-                                            QS_FUN_(t);
-                                        QS_END_()
-
-                                        (void)QEP_TRIG_(t, QEP_EMPTY_SIG_);
-                                    }
-                                    t = m_state;         //  set to super of t
-                                    iq = ip;
-                                    do {
-                                        if (t == path[iq]) {   // is this LCA?
-                                                           // do not enter LCA
-                                            ip = (int8_t)(iq - 1);
-                                            iq = (int8_t)(-1);   //break inner
-                                            r = Q_RET_HANDLED;   //break outer
-                                        }
-                                        else {
-                                            --iq;
-                                        }
-                                    } while (iq >= (int8_t)0);
-                                } while (r != Q_RET_HANDLED);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-                       // retrace the entry path in reverse (desired) order...
-        for (; ip >= (int8_t)0; --ip) {
-            QEP_ENTER_(path[ip])                             // enter path[ip]
-        }
-        t = path[0];                         // stick the target into register
-        m_state = t;                               // update the current state
-
-                                         // drill into the target hierarchy...
-        while (QEP_TRIG_(t, Q_INIT_SIG) == Q_RET_TRAN) {
-
-            QS_BEGIN_(QS_QEP_STATE_INIT, QS::smObj_, this)
-                QS_OBJ_(this);                    // this state machine object
-                QS_FUN_(t);                        // the source (pseudo)state
-                QS_FUN_(m_state);              // the target of the transition
-            QS_END_()
-
-            ip = (int8_t)0;
-            path[0] = m_state;
-            (void)QEP_TRIG_(m_state, QEP_EMPTY_SIG_);       // find superstate
-            while (m_state != t) {
-                ++ip;
-                path[ip] = m_state;
-                (void)QEP_TRIG_(m_state, QEP_EMPTY_SIG_);   // find superstate
-            }
-            m_state = path[0];
-                                               // entry path must not overflow
-            Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_);
-
-            do {       // retrace the entry path in reverse (correct) order...
-                QEP_ENTER_(path[ip])                         // enter path[ip]
-                --ip;
-            } while (ip >= (int8_t)0);
-
-            t = path[0];
-        }
-
-        QS_BEGIN_(QS_QEP_TRAN, QS::smObj_, this)
-            QS_TIME_();                                          // time stamp
-            QS_SIG_(e->sig);                        // the signal of the event
-            QS_OBJ_(this);                        // this state machine object
-            QS_FUN_(src);                      // the source of the transition
-            QS_FUN_(t);                                // the new active state
-        QS_END_()
-
-    }
-    else {                                             // transition not taken
-#ifdef Q_SPY
-        if (r == Q_RET_IGNORED) {                            // event ignored?
-
-            QS_BEGIN_(QS_QEP_IGNORED, QS::smObj_, this)
-                QS_TIME_();                                      // time stamp
-                QS_SIG_(e->sig);                    // the signal of the event
-                QS_OBJ_(this);                    // this state machine object
-                QS_FUN_(t);                               // the current state
-            QS_END_()
-
-        }
-        else {                                                // event handled
-
-            QS_BEGIN_(QS_QEP_INTERN_TRAN, QS::smObj_, this)
-                QS_TIME_();                                      // time stamp
-                QS_SIG_(e->sig);                    // the signal of the event
-                QS_OBJ_(this);                    // this state machine object
-                QS_FUN_(s);                // the state that handled the event
-            QS_END_()
-
-        }
-#endif
-    }
-    m_state = t;                 // set new state or restore the current state
-}
-
-// "qf_pkg.h" ================================================================
-                                    // QF-specific interrupt locking/unlocking
-#ifndef QF_INT_KEY_TYPE
-
-    /// \brief This is an internal macro for defining the interrupt lock key.
-    ///
-    /// The purpose of this macro is to enable writing the same code for the
-    /// case when interrupt key is defined and when it is not. If the macro
-    /// #QF_INT_KEY_TYPE is defined, this internal macro provides the
-    /// definition of the lock key variable. Otherwise this macro is empty.
-    /// \sa #QF_INT_KEY_TYPE
-    #define QF_INT_LOCK_KEY_
-
-    /// \brief This is an internal macro for locking interrupts.
-    ///
-    /// The purpose of this macro is to enable writing the same code for the
-    /// case when interrupt key is defined and when it is not. If the macro
-    /// #QF_INT_KEY_TYPE is defined, this internal macro invokes #QF_INT_LOCK
-    /// passing the key variable as the parameter. Otherwise #QF_INT_LOCK
-    /// is invoked with a dummy parameter.
-    /// \sa #QF_INT_LOCK, #QK_INT_LOCK
-    #define QF_INT_LOCK_()      QF_INT_LOCK(dummy)
-
-    /// \brief This is an internal macro for unlocking interrupts.
-    ///
-    /// The purpose of this macro is to enable writing the same code for the
-    /// case when interrupt key is defined and when it is not. If the macro
-    /// #QF_INT_KEY_TYPE is defined, this internal macro invokes
-    /// #QF_INT_UNLOCK passing the key variable as the parameter.
-    /// Otherwise #QF_INT_UNLOCK is invoked with a dummy parameter.
-    /// \sa #QF_INT_UNLOCK, #QK_INT_UNLOCK
-    #define QF_INT_UNLOCK_()    QF_INT_UNLOCK(dummy)
-#else
-    #define QF_INT_LOCK_KEY_    QF_INT_KEY_TYPE intLockKey_;
-    #define QF_INT_LOCK_()      QF_INT_LOCK(intLockKey_)
-    #define QF_INT_UNLOCK_()    QF_INT_UNLOCK(intLockKey_)
-#endif
-
-// package-scope objects -----------------------------------------------------
-extern QTimeEvt *QF_timeEvtListHead_;  ///< head of linked list of time events
-extern QF_EPOOL_TYPE_ QF_pool_[QF_MAX_EPOOL];        ///< allocate event pools
-extern uint8_t QF_maxPool_;                  ///< # of initialized event pools
-extern QSubscrList *QF_subscrList_;             ///< the subscriber list array
-extern QSignal QF_maxSignal_;                ///< the maximum published signal
-
-//............................................................................
-/// \brief Structure representing a free block in the Native QF Memory Pool
-/// \sa ::QMPool
-struct QFreeBlock {
-    QFreeBlock *m_next;
-};
-
-/// \brief access to the poolId of an event \a e_
-#define EVT_POOL_ID(e_)     ((e_)->poolId_)
-
-/// \brief access to the refCtr of an event \a e_
-#define EVT_REF_CTR(e_)     ((e_)->refCtr_)
-
-/// \brief increment the refCtr of an event \a e_
-#define EVT_INC_REF_CTR(e_) (++((QEvent *)(e_))->refCtr_)
-
-/// \brief decrement the refCtr of an event \a e_
-#define EVT_DEC_REF_CTR(e_) (--((QEvent *)(e_))->refCtr_)
-
-// "qa_defer.cpp" ============================================================
-//............................................................................
-void QActive::defer(QEQueue *eq, QEvent const *e) {
-    eq->postFIFO(e);
-}
-//............................................................................
-uint8_t QActive::recall(QEQueue *eq) {
-    QEvent const *e = eq->get();    // try to get an event from deferred queue
-    if (e != (QEvent *)0) {                                // event available?
-
-        postLIFO(e);      // post it to the front of the Active Object's queue
-
-        QF_INT_LOCK_KEY_
-        QF_INT_LOCK_();
-
-        if (EVT_POOL_ID(e) != (uint8_t)0) {          // is it a dynamic event?
-
-            // after posting to the AO's queue the event must be referenced
-            // at least twice: once in the deferred event queue (eq->get()
-            // did NOT decrement the reference counter) and once in the
-            // AO's event queue.
-            Q_ASSERT(EVT_REF_CTR(e) > (uint8_t)1);
-
-            // we need to decrement the reference counter once, to account
-            // for removing the event from the deferred event queue.
-            //
-            EVT_DEC_REF_CTR(e);             // decrement the reference counter
-        }
-
-        QF_INT_UNLOCK_();
-
-        return (uint8_t)1;                                   // event recalled
-    }
-    else {
-        return (uint8_t)0;                               // event not recalled
-    }
-}
-
-// "qa_fifo.cpp" =============================================================
-//............................................................................
-#ifndef Q_SPY
-void QActive::postFIFO(QEvent const *e) {
-#else
-void QActive::postFIFO(QEvent const *e, void const *sender) {
-#endif
-
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-
-    QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_POST_FIFO, QS::aoObj_, this)
-        QS_TIME_();                                               // timestamp
-        QS_OBJ_(sender);                                  // the sender object
-        QS_SIG_(e->sig);                            // the signal of the event
-        QS_OBJ_(this);                                   // this active object
-        QS_U8_(EVT_POOL_ID(e));                    // the pool Id of the event
-        QS_U8_(EVT_REF_CTR(e));                  // the ref count of the event
-        QS_EQC_(m_eQueue.m_nFree);                   // number of free entries
-        QS_EQC_(m_eQueue.m_nMin);                // min number of free entries
-    QS_END_NOLOCK_()
-
-    if (EVT_POOL_ID(e) != (uint8_t)0) {              // is it a dynamic event?
-        EVT_INC_REF_CTR(e);                 // increment the reference counter
-    }
-
-    if (m_eQueue.m_frontEvt == (QEvent *)0) {           // is the queue empty?
-        m_eQueue.m_frontEvt = e;                     // deliver event directly
-        QACTIVE_EQUEUE_SIGNAL_(this);                // signal the event queue
-    }
-    else {               // queue is not empty, leave event in the ring-buffer
-                                        // queue must accept all posted events
-        Q_ASSERT(m_eQueue.m_nFree != (QEQueueCtr)0);
-        m_eQueue.m_ring[m_eQueue.m_head] = e;//insert e into the buffer (FIFO)
-        if (m_eQueue.m_head == (QEQueueCtr)0) {      // need to wrap the head?
-            m_eQueue.m_head = m_eQueue.m_end;                   // wrap around
-        }
-        --m_eQueue.m_head;
-
-        --m_eQueue.m_nFree;                    // update number of free events
-        if (m_eQueue.m_nMin > m_eQueue.m_nFree) {
-            m_eQueue.m_nMin = m_eQueue.m_nFree;       // update minimum so far
-        }
-    }
-    QF_INT_UNLOCK_();
-}
-
-// "qa_get_.cpp" =============================================================
-QEvent const *QActive::get_(void) {
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-
-    QACTIVE_EQUEUE_WAIT_(this);           // wait for event to arrive directly
-
-    QEvent const *e = m_eQueue.m_frontEvt;
-
-    if (m_eQueue.m_nFree != m_eQueue.m_end) { //any events in the ring buffer?
-                                                 // remove event from the tail
-        m_eQueue.m_frontEvt = m_eQueue.m_ring[m_eQueue.m_tail];
-        if (m_eQueue.m_tail == (QEQueueCtr)0) {      // need to wrap the tail?
-            m_eQueue.m_tail = m_eQueue.m_end;                   // wrap around
-        }
-        --m_eQueue.m_tail;
-
-        ++m_eQueue.m_nFree;          // one more free event in the ring buffer
-
-        QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_GET, QS::aoObj_, this)
-            QS_TIME_();                                           // timestamp
-            QS_SIG_(e->sig);                       // the signal of this event
-            QS_OBJ_(this);                               // this active object
-            QS_U8_(EVT_POOL_ID(e));                // the pool Id of the event
-            QS_U8_(EVT_REF_CTR(e));              // the ref count of the event
-            QS_EQC_(m_eQueue.m_nFree);               // number of free entries
-        QS_END_NOLOCK_()
-    }
-    else {
-        m_eQueue.m_frontEvt = (QEvent *)0;          // the queue becomes empty
-        QACTIVE_EQUEUE_ONEMPTY_(this);
-
-        QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_GET_LAST, QS::aoObj_, this)
-            QS_TIME_();                                           // timestamp
-            QS_SIG_(e->sig);                       // the signal of this event
-            QS_OBJ_(this);                               // this active object
-            QS_U8_(EVT_POOL_ID(e));                // the pool Id of the event
-            QS_U8_(EVT_REF_CTR(e));              // the ref count of the event
-        QS_END_NOLOCK_()
-    }
-    QF_INT_UNLOCK_();
-    return e;
-}
-//............................................................................
-uint32_t QF::getQueueMargin(uint8_t prio) {
-    Q_REQUIRE((prio <= (uint8_t)QF_MAX_ACTIVE)
-              && (active_[prio] != (QActive *)0));
-
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-    uint32_t margin = (uint32_t)(active_[prio]->m_eQueue.m_nMin);
-    QF_INT_UNLOCK_();
-
-    return margin;
-}
-
-// "qa_lifo.cpp" =============================================================
-void QActive::postLIFO(QEvent const *e) {
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-
-    QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_POST_LIFO, QS::aoObj_, this)
-        QS_TIME_();                                               // timestamp
-        QS_SIG_(e->sig);                           // the signal of this event
-        QS_OBJ_(this);                                   // this active object
-        QS_U8_(EVT_POOL_ID(e));                    // the pool Id of the event
-        QS_U8_(EVT_REF_CTR(e));                  // the ref count of the event
-        QS_EQC_(m_eQueue.m_nFree);                   // number of free entries
-        QS_EQC_(m_eQueue.m_nMin);                // min number of free entries
-    QS_END_NOLOCK_()
-
-    if (EVT_POOL_ID(e) != (uint8_t)0) {              // is it a dynamic event?
-        EVT_INC_REF_CTR(e);                 // increment the reference counter
-    }
-
-    if (m_eQueue.m_frontEvt == (QEvent *)0) {           // is the queue empty?
-        m_eQueue.m_frontEvt = e;                     // deliver event directly
-        QACTIVE_EQUEUE_SIGNAL_(this);                // signal the event queue
-    }
-    else {               // queue is not empty, leave event in the ring-buffer
-                                        // queue must accept all posted events
-        Q_ASSERT(m_eQueue.m_nFree != (QEQueueCtr)0);
-
-        ++m_eQueue.m_tail;
-        if (m_eQueue.m_tail == m_eQueue.m_end) {     // need to wrap the tail?
-            m_eQueue.m_tail = (QEQueueCtr)0;                    // wrap around
-        }
-
-        m_eQueue.m_ring[m_eQueue.m_tail] = m_eQueue.m_frontEvt;
-        m_eQueue.m_frontEvt = e;                         // put event to front
-
-        --m_eQueue.m_nFree;                    // update number of free events
-        if (m_eQueue.m_nMin > m_eQueue.m_nFree) {
-            m_eQueue.m_nMin = m_eQueue.m_nFree;       // update minimum so far
-        }
-    }
-    QF_INT_UNLOCK_();
-}
-
-// "qa_sub.cpp" ==============================================================
-void QActive::subscribe(QSignal sig) const {
-    uint8_t p = m_prio;
-    Q_REQUIRE(((QSignal)Q_USER_SIG <= sig)
-              && (sig < QF_maxSignal_)
-              && ((uint8_t)0 < p) && (p <= (uint8_t)QF_MAX_ACTIVE)
-              && (QF::active_[p] == this));
-
-    uint8_t i = Q_ROM_BYTE(QF_div8Lkup[p]);
-
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-
-    QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_SUBSCRIBE, QS::aoObj_, this)
-        QS_TIME_();                                               // timestamp
-        QS_SIG_(sig);                              // the signal of this event
-        QS_OBJ_(this);                                   // this active object
-    QS_END_NOLOCK_()
-                                                       // set the priority bit
-    QF_subscrList_[sig].m_bits[i] |= Q_ROM_BYTE(QF_pwr2Lkup[p]);
-    QF_INT_UNLOCK_();
-}
-
-// "qa_usub.cpp" =============================================================
-void QActive::unsubscribe(QSignal sig) const {
-    uint8_t p = m_prio;
-    Q_REQUIRE(((QSignal)Q_USER_SIG <= sig)
-              && (sig < QF_maxSignal_)
-              && ((uint8_t)0 < p) && (p <= (uint8_t)QF_MAX_ACTIVE)
-              && (QF::active_[p] == this));
-
-    uint8_t i = Q_ROM_BYTE(QF_div8Lkup[p]);
-
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-
-    QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_UNSUBSCRIBE, QS::aoObj_, this)
-        QS_TIME_();                                               // timestamp
-        QS_SIG_(sig);                              // the signal of this event
-        QS_OBJ_(this);                                   // this active object
-    QS_END_NOLOCK_()
-                                                     // clear the priority bit
-    QF_subscrList_[sig].m_bits[i] &= Q_ROM_BYTE(QF_invPwr2Lkup[p]);
-    QF_INT_UNLOCK_();
-}
-
-// "qa_usuba.cpp" ============================================================
-void QActive::unsubscribeAll(void) const {
-    uint8_t p = m_prio;
-    Q_REQUIRE(((uint8_t)0 < p) && (p <= (uint8_t)QF_MAX_ACTIVE)
-              && (QF::active_[p] == this));
-
-    uint8_t i = Q_ROM_BYTE(QF_div8Lkup[p]);
-
-    QSignal sig;
-    for (sig = (QSignal)Q_USER_SIG; sig < QF_maxSignal_; ++sig) {
-        QF_INT_LOCK_KEY_
-        QF_INT_LOCK_();
-        if ((QF_subscrList_[sig].m_bits[i] & Q_ROM_BYTE(QF_pwr2Lkup[p]))
-             != 0)
-        {
-
-            QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_UNSUBSCRIBE, QS::aoObj_, this)
-                QS_TIME_();                                       // timestamp
-                QS_SIG_(sig);                      // the signal of this event
-                QS_OBJ_(this);                           // this active object
-            QS_END_NOLOCK_()
-                                                     // clear the priority bit
-            QF_subscrList_[sig].m_bits[i] &= Q_ROM_BYTE(QF_invPwr2Lkup[p]);
-        }
-        QF_INT_UNLOCK_();
-    }
-}
-
-// "qeq_fifo.cpp" ============================================================
-void QEQueue::postFIFO(QEvent const *e) {
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-
-    QS_BEGIN_NOLOCK_(QS_QF_EQUEUE_POST_FIFO, QS::eqObj_, this)
-        QS_TIME_();                                               // timestamp
-        QS_SIG_(e->sig);                           // the signal of this event
-        QS_OBJ_(this);                                    // this queue object
-        QS_U8_(EVT_POOL_ID(e));                    // the pool Id of the event
-        QS_U8_(EVT_REF_CTR(e));                  // the ref count of the event
-        QS_EQC_(m_nFree);                            // number of free entries
-        QS_EQC_(m_nMin);                         // min number of free entries
-    QS_END_NOLOCK_()
-
-    if (EVT_POOL_ID(e) != (uint8_t)0) {              // is it a dynamic event?
-        EVT_INC_REF_CTR(e);                 // increment the reference counter
-    }
-
-    if (m_frontEvt == (QEvent *)0) {                    // is the queue empty?
-        m_frontEvt = e;                              // deliver event directly
-    }
-    else {               // queue is not empty, leave event in the ring-buffer
-               // the queue must be able to accept the event (cannot overflow)
-        Q_ASSERT(m_nFree != (QEQueueCtr)0);
-
-        m_ring[m_head] = e;             // insert event into the buffer (FIFO)
-        if (m_head == (QEQueueCtr)0) {               // need to wrap the head?
-            m_head = m_end;                                     // wrap around
-        }
-        --m_head;
-
-        --m_nFree;                             // update number of free events
-        if (m_nMin > m_nFree) {
-            m_nMin = m_nFree;                         // update minimum so far
-        }
-    }
-    QF_INT_UNLOCK_();
-}
-
-// "qeq_get.cpp" =============================================================
-QEvent const *QEQueue::get(void) {
-    QEvent const *e;
-    QF_INT_LOCK_KEY_
-
-    QF_INT_LOCK_();
-    if (m_frontEvt == (QEvent *)0) {                    // is the queue empty?
-        e = (QEvent *)0;                    // no event available at this time
-    }
-    else {
-        e = m_frontEvt;
-
-        if (m_nFree != m_end) {          // any events in the the ring buffer?
-            m_frontEvt = m_ring[m_tail];         // remove event from the tail
-            if (m_tail == (QEQueueCtr)0) {           // need to wrap the tail?
-                m_tail = m_end;                                 // wrap around
-            }
-            --m_tail;
-
-            ++m_nFree;               // one more free event in the ring buffer
-
-            QS_BEGIN_NOLOCK_(QS_QF_EQUEUE_GET, QS::eqObj_, this)
-                QS_TIME_();                                       // timestamp
-                QS_SIG_(e->sig);                   // the signal of this event
-                QS_OBJ_(this);                            // this queue object
-                QS_U8_(EVT_POOL_ID(e));            // the pool Id of the event
-                QS_U8_(EVT_REF_CTR(e));          // the ref count of the event
-                QS_EQC_(m_nFree);                    // number of free entries
-            QS_END_NOLOCK_()
-        }
-        else {
-            m_frontEvt = (QEvent *)0;               // the queue becomes empty
-
-            QS_BEGIN_NOLOCK_(QS_QF_EQUEUE_GET_LAST, QS::eqObj_, this)
-                QS_TIME_();                                       // timestamp
-                QS_SIG_(e->sig);                   // the signal of this event
-                QS_OBJ_(this);                            // this queue object
-                QS_U8_(EVT_POOL_ID(e));            // the pool Id of the event
-                QS_U8_(EVT_REF_CTR(e));          // the ref count of the event
-            QS_END_NOLOCK_()
-        }
-    }
-    QF_INT_UNLOCK_();
-    return e;
-}
-
-// "qeq_init.cpp" ============================================================
-void QEQueue::init(QEvent const *qSto[], QEQueueCtr qLen) {
-    m_frontEvt = (QEvent *)0;                        // no events in the queue
-    m_ring     = &qSto[0];
-    m_end      = qLen;
-    m_head     = (QEQueueCtr)0;
-    m_tail     = (QEQueueCtr)0;
-    m_nFree    = qLen;
-    m_nMin     = qLen;
-
-    QS_INT_LOCK_KEY_
-    QS_BEGIN_(QS_QF_EQUEUE_INIT, QS::eqObj_, this)
-        QS_OBJ_(qSto);                                  // this QEQueue object
-        QS_EQC_(qLen);                              // the length of the queue
-    QS_END_()
-}
-
-// "qeq_lifo.cpp" ============================================================
-void QEQueue::postLIFO(QEvent const *e) {
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-
-    QS_BEGIN_NOLOCK_(QS_QF_EQUEUE_POST_LIFO, QS::eqObj_, this)
-        QS_TIME_();                                               // timestamp
-        QS_SIG_(e->sig);                           // the signal of this event
-        QS_OBJ_(this);                                    // this queue object
-        QS_U8_(EVT_POOL_ID(e));                    // the pool Id of the event
-        QS_U8_(EVT_REF_CTR(e));                  // the ref count of the event
-        QS_EQC_(m_nFree);                            // number of free entries
-        QS_EQC_(m_nMin);                         // min number of free entries
-    QS_END_NOLOCK_()
-
-    if (EVT_POOL_ID(e) != (uint8_t)0) {              // is it a dynamic event?
-        EVT_INC_REF_CTR(e);                 // increment the reference counter
-    }
-
-    if (m_frontEvt != (QEvent *)0) {                // is the queue not empty?
-               // the queue must be able to accept the event (cannot overflow)
-        Q_ASSERT(m_nFree != (QEQueueCtr)0);
-
-        ++m_tail;
-        if (m_tail == m_end) {                       // need to wrap the tail?
-            m_tail = (QEQueueCtr)0;                             // wrap around
-        }
-
-        m_ring[m_tail] = m_frontEvt;               // buffer the old front evt
-
-        --m_nFree;                             // update number of free events
-        if (m_nMin > m_nFree) {
-            m_nMin = m_nFree;                         // update minimum so far
-        }
-    }
-
-    m_frontEvt = e;                        // stick the new event to the front
-
-    QF_INT_UNLOCK_();
-}
-
-// "qf_act.cpp" ==============================================================
-// public objects ------------------------------------------------------------
-QActive *QF::active_[QF_MAX_ACTIVE + 1];        // to be used by QF ports only
-uint8_t QF_intLockNest_;                       // interrupt-lock nesting level
-
-//............................................................................
-//lint -e970 -e971               ignore MISRA rules 13 and 14 in this function
-const char Q_ROM * Q_ROM_VAR QF::getVersion(void) {
-    static char const Q_ROM Q_ROM_VAR version[] = {
-        (char)(((QP_VERSION >> 12U) & 0xFU) + (uint8_t)'0'),
-        '.',
-        (char)(((QP_VERSION >>  8U) & 0xFU) + (uint8_t)'0'),
-        '.',
-        (char)(((QP_VERSION >>  4U) & 0xFU) + (uint8_t)'0'),
-        (char)((QP_VERSION          & 0xFU) + (uint8_t)'0'),
-        '\0'
-    };
-    return version;
-}
-//............................................................................
-void QF::add_(QActive *a) {
-    uint8_t p = a->m_prio;
-
-    Q_REQUIRE(((uint8_t)0 < p) && (p <= (uint8_t)QF_MAX_ACTIVE)
-              && (active_[p] == (QActive *)0));
-
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-
-    active_[p] = a;            // registger the active object at this priority
-
-    QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_ADD, QS::aoObj_, a)
-        QS_TIME_();                                               // timestamp
-        QS_OBJ_(a);                                       // the active object
-        QS_U8_(p);                        // the priority of the active object
-    QS_END_NOLOCK_()
-
-    QF_INT_UNLOCK_();
-}
-//............................................................................
-void QF::remove_(QActive const *a) {
-    uint8_t p = a->m_prio;
-
-    Q_REQUIRE(((uint8_t)0 < p) && (p <= (uint8_t)QF_MAX_ACTIVE)
-              && (active_[p] == a));
-
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-
-    active_[p] = (QActive *)0;                   // free-up the priority level
-
-    QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_REMOVE, QS::aoObj_, a)
-        QS_TIME_();                                               // timestamp
-        QS_OBJ_(a);                                       // the active object
-        QS_U8_(p);                        // the priority of the active object
-    QS_END_NOLOCK_()
-
-    QF_INT_UNLOCK_();
-}
-
-// "qf_gc.cpp" ===============================================================
-void QF::gc(QEvent const *e) {
-    if (EVT_POOL_ID(e) != (uint8_t)0) {              // is it a dynamic event?
-        QF_INT_LOCK_KEY_
-        QF_INT_LOCK_();
-
-        if (EVT_REF_CTR(e) > (uint8_t)1) {   // isn't this the last reference?
-            EVT_DEC_REF_CTR(e);                   // decrement the ref counter
-
-            QS_BEGIN_NOLOCK_(QS_QF_GC_ATTEMPT, (void *)0, (void *)0)
-                QS_TIME_();                                       // timestamp
-                QS_SIG_(e->sig);                    // the signal of the event
-                QS_U8_(EVT_POOL_ID(e));            // the pool Id of the event
-                QS_U8_(EVT_REF_CTR(e));          // the ref count of the event
-            QS_END_NOLOCK_()
-
-            QF_INT_UNLOCK_();
-        }
-        else {         // this is the last reference to this event, recycle it
-            uint8_t idx = (uint8_t)(EVT_POOL_ID(e) - 1);
-
-            QS_BEGIN_NOLOCK_(QS_QF_GC, (void *)0, (void *)0)
-                QS_TIME_();                                       // timestamp
-                QS_SIG_(e->sig);                    // the signal of the event
-                QS_U8_(EVT_POOL_ID(e));            // the pool Id of the event
-                QS_U8_(EVT_REF_CTR(e));          // the ref count of the event
-            QS_END_NOLOCK_()
-
-            QF_INT_UNLOCK_();
-
-            Q_ASSERT(idx < QF_maxPool_);
-
-#ifdef Q_EVT_CTOR
-            //lint -e1773                           Attempt to cast away const
-            ((QEvent *)e)->~QEvent();     // call the xtor, cast 'const' away,
-                             // which is legitimate, because it's a pool event
-#endif
-            //lint -e1773                           Attempt to cast away const
-            QF_EPOOL_PUT_(QF_pool_[idx], (QEvent *)e);   // cast 'const' away,
-                             // which is legitimate, because it's a pool event
-        }
-    }
-}
-
-// "qf_log2.cpp" =============================================================
-uint8_t const Q_ROM Q_ROM_VAR QF_log2Lkup[256] = {
-    0U, 1U, 2U, 2U, 3U, 3U, 3U, 3U, 4U, 4U, 4U, 4U, 4U, 4U, 4U, 4U,
-    5U, 5U, 5U, 5U, 5U, 5U, 5U, 5U, 5U, 5U, 5U, 5U, 5U, 5U, 5U, 5U,
-    6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U,
-    6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U,
-    7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U,
-    7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U,
-    7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U,
-    7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U,
-    8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U,
-    8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U,
-    8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U,
-    8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U,
-    8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U,
-    8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U,
-    8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U,
-    8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U, 8U
-};
-
-// "qf_new.cpp" ==============================================================
-QEvent *QF::new_(uint16_t evtSize, QSignal sig) {
-                    // find the pool id that fits the requested event size ...
-    uint8_t idx = (uint8_t)0;
-    while (evtSize > QF_EPOOL_EVENT_SIZE_(QF_pool_[idx])) {
-        ++idx;
-        Q_ASSERT(idx < QF_maxPool_);     // cannot run out of registered pools
-    }
-
-    QS_INT_LOCK_KEY_
-    QS_BEGIN_(QS_QF_NEW, (void *)0, (void *)0)
-        QS_TIME_();                                               // timestamp
-        QS_EVS_(evtSize);                             // the size of the event
-        QS_SIG_(sig);                               // the signal of the event
-    QS_END_()
-
-    QEvent *e;
-    QF_EPOOL_GET_(QF_pool_[idx], e);
-    Q_ASSERT(e != (QEvent *)0);             // pool must not run out of events
-
-    e->sig = sig;                                 // set signal for this event
-    EVT_POOL_ID(e) = (uint8_t)(idx + 1);     // store the pool ID in the event
-    EVT_REF_CTR(e) = (uint8_t)0;             // set the reference counter to 0
-
-    return e;
-}
-
-// "qf_pool.cpp" =============================================================
-// Package-scope objects -----------------------------------------------------
-QF_EPOOL_TYPE_ QF_pool_[QF_MAX_EPOOL];             // allocate the event pools
-uint8_t QF_maxPool_;                      // number of initialized event pools
-
-//............................................................................
-void QF::poolInit(void *poolSto, uint32_t poolSize, QEventSize evtSize) {
-                         // cannot exceed the number of available memory pools
-    Q_REQUIRE(QF_maxPool_ < (uint8_t)Q_DIM(QF_pool_));
-               // please initialize event pools in ascending order of evtSize:
-    Q_REQUIRE((QF_maxPool_ == (uint8_t)0)
-              || (QF_EPOOL_EVENT_SIZE_(QF_pool_[QF_maxPool_ - 1]) < evtSize));
-    QF_EPOOL_INIT_(QF_pool_[QF_maxPool_], poolSto, poolSize, evtSize);
-    ++QF_maxPool_;                                            // one more pool
-}
-
-// "qf_psini.cpp" ============================================================
-// Package-scope objects -----------------------------------------------------
-QSubscrList *QF_subscrList_;
-QSignal QF_maxSignal_;
-
-//............................................................................
-void QF::psInit(QSubscrList *subscrSto, QSignal maxSignal) {
-    QF_subscrList_ = subscrSto;
-    QF_maxSignal_ = maxSignal;
-}
-
-// "qf_pspub.cpp" ============================================================
-#ifndef Q_SPY
-void QF::publish(QEvent const *e) {
-#else
-void QF::publish(QEvent const *e, void const *sender) {
-#endif
-         // make sure that the published signal is within the configured range
-    Q_REQUIRE(e->sig < QF_maxSignal_);
-
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-
-    QS_BEGIN_NOLOCK_(QS_QF_PUBLISH, (void *)0, (void *)0)
-        QS_TIME_();                                           // the timestamp
-        QS_OBJ_(sender);                                  // the sender object
-        QS_SIG_(e->sig);                            // the signal of the event
-        QS_U8_(EVT_POOL_ID(e));                    // the pool Id of the event
-        QS_U8_(EVT_REF_CTR(e));                  // the ref count of the event
-    QS_END_NOLOCK_()
-
-    if (EVT_POOL_ID(e) != (uint8_t)0) {              // is it a dynamic event?
-        EVT_INC_REF_CTR(e);         // increment the reference counter, NOTE01
-    }
-    QF_INT_UNLOCK_();
-
-#if (QF_MAX_ACTIVE <= 8)
-    uint8_t tmp = QF_subscrList_[e->sig].m_bits[0];
-    while (tmp != (uint8_t)0) {
-        uint8_t p = Q_ROM_BYTE(QF_log2Lkup[tmp]);
-        tmp &= Q_ROM_BYTE(QF_invPwr2Lkup[p]);      // clear the subscriber bit
-        Q_ASSERT(active_[p] != (QActive *)0);            // must be registered
-
-                           // POST() asserts internally if the queue overflows
-        active_[p]->POST(e, sender);
-    }
-#else
-    uint8_t i = Q_DIM(QF_subscrList_[0].m_bits);// number of bytes in the list
-    do {                       // go through all bytes in the subsciption list
-        --i;
-        uint8_t tmp = QF_subscrList_[e->sig].m_bits[i];
-        while (tmp != (uint8_t)0) {
-            uint8_t p = Q_ROM_BYTE(QF_log2Lkup[tmp]);
-            tmp &= Q_ROM_BYTE(QF_invPwr2Lkup[p]);  // clear the subscriber bit
-            p = (uint8_t)(p + (i << 3));                // adjust the priority
-            Q_ASSERT(active_[p] != (QActive *)0);        // must be registered
-
-                           // POST() asserts internally if the queue overflows
-            active_[p]->POST(e, sender);
-        }
-    } while (i != (uint8_t)0);
-#endif
-
-    gc(e);                            // run the garbage collector, see NOTE01
-}
-
-// "qf_pwr2.cpp" =============================================================
-// Global objects ------------------------------------------------------------
-uint8_t const Q_ROM Q_ROM_VAR QF_pwr2Lkup[65] = {
-    0x00U,                                                  // unused location
-    0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U,
-    0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U,
-    0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U,
-    0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U,
-    0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U,
-    0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U,
-    0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U,
-    0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U
-};
-
-uint8_t const Q_ROM Q_ROM_VAR QF_invPwr2Lkup[65] = {
-    0xFFU,                                                  // unused location
-    0xFEU, 0xFDU, 0xFBU, 0xF7U, 0xEFU, 0xDFU, 0xBFU, 0x7FU,
-    0xFEU, 0xFDU, 0xFBU, 0xF7U, 0xEFU, 0xDFU, 0xBFU, 0x7FU,
-    0xFEU, 0xFDU, 0xFBU, 0xF7U, 0xEFU, 0xDFU, 0xBFU, 0x7FU,
-    0xFEU, 0xFDU, 0xFBU, 0xF7U, 0xEFU, 0xDFU, 0xBFU, 0x7FU,
-    0xFEU, 0xFDU, 0xFBU, 0xF7U, 0xEFU, 0xDFU, 0xBFU, 0x7FU,
-    0xFEU, 0xFDU, 0xFBU, 0xF7U, 0xEFU, 0xDFU, 0xBFU, 0x7FU,
-    0xFEU, 0xFDU, 0xFBU, 0xF7U, 0xEFU, 0xDFU, 0xBFU, 0x7FU,
-    0xFEU, 0xFDU, 0xFBU, 0xF7U, 0xEFU, 0xDFU, 0xBFU, 0x7FU
-};
-
-uint8_t const Q_ROM Q_ROM_VAR QF_div8Lkup[65] = {
-    0U,                                                     // unused location
-    0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U,
-    1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U,
-    2U, 2U, 2U, 2U, 2U, 2U, 2U, 2U,
-    3U, 3U, 3U, 3U, 3U, 3U, 3U, 3U,
-    4U, 4U, 4U, 4U, 4U, 4U, 4U, 4U,
-    5U, 5U, 5U, 5U, 5U, 5U, 5U, 5U,
-    6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U,
-    7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U
-};
-
-// "qf_tick.cpp" =============================================================
-#ifndef Q_SPY
-void QF::tick(void) {                                            // see NOTE01
-#else
-void QF::tick(void const *sender) {
-#endif
-
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-
-    QS_BEGIN_NOLOCK_(QS_QF_TICK, (void *)0, (void *)0)
-        QS_TEC_(++QS::tickCtr_);                           // the tick counter
-    QS_END_NOLOCK_()
-
-    QTimeEvt *t = QF_timeEvtListHead_;
-    while (t != (QTimeEvt *)0) {
-        --t->m_ctr;
-        if (t->m_ctr == (QTimeEvtCtr)0) {  // is the time evt about to expire?
-            if (t->m_interval != (QTimeEvtCtr)0) {//is it a periodic time evt?
-                t->m_ctr = t->m_interval;                // rearm the time evt
-            }
-            else {   // one-shot time evt, disarm by removing it from the list
-                if (t == QF_timeEvtListHead_) {
-                    QF_timeEvtListHead_ = t->m_next;
-                }
-                else {
-                    if (t->m_next != (QTimeEvt *)0) {// not the last time evt?
-                        t->m_next->m_prev = t->m_prev;
-                    }
-                    t->m_prev->m_next = t->m_next;
-                }
-                t->m_prev = (QTimeEvt *)0;     // mark the time event disarmed
-
-                QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_AUTO_DISARM, QS::teObj_, t)
-                    QS_OBJ_(t);                      // this time event object
-                    QS_OBJ_(t->m_act);                     // the active object
-                QS_END_NOLOCK_()
-            }
-
-            QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_POST, QS::teObj_, t)
-                QS_TIME_();                                       // timestamp
-                QS_OBJ_(t);                           // the time event object
-                QS_SIG_(t->sig);              // the signal of this time event
-                QS_OBJ_(t->m_act);                        // the active object
-            QS_END_NOLOCK_()
-
-            QF_INT_UNLOCK_();   // unlock interrupts before calling QF service
-
-                           // POST() asserts internally if the queue overflows
-            t->m_act->POST(t, sender);
-        }
-        else {
-            QF_INT_UNLOCK_();
-            static uint8_t volatile dummy;
-            dummy = (uint8_t)0;      // execute a few instructions, see NOTE02
-        }
-
-        QF_INT_LOCK_();           // lock interrupts again to advance the link
-        t = t->m_next;
-    }
-    QF_INT_UNLOCK_();
-}
-
-// "qmp_get.cpp" =============================================================
-void *QMPool::get(void) {
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-
-    QFreeBlock *fb = (QFreeBlock *)m_free;         // get a free block or NULL
-    if (fb != (QFreeBlock *)0) {                      // free block available?
-        m_free = fb->m_next;        // adjust list head to the next free block
-        --m_nFree;                                      // one free block less
-        if (m_nMin > m_nFree) {
-            m_nMin = m_nFree;                   // remember the minimum so far
-        }
-    }
-
-    QS_BEGIN_NOLOCK_(QS_QF_MPOOL_GET, QS::mpObj_, m_start)
-        QS_TIME_();                                               // timestamp
-        QS_OBJ_(m_start);                   // the memory managed by this pool
-        QS_MPC_(m_nFree);             // the number of free blocks in the pool
-        QS_MPC_(m_nMin);     // the mninimum number of free blocks in the pool
-    QS_END_NOLOCK_()
-
-    QF_INT_UNLOCK_();
-    return fb;               // return the block or NULL pointer to the caller
-}
-//............................................................................
-uint32_t QF::getPoolMargin(uint8_t poolId) {
-    Q_REQUIRE(((uint8_t)1 <= poolId) && (poolId <= QF_maxPool_));
-
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-    uint32_t margin = (uint32_t)QF_pool_[poolId - (uint8_t)1].m_nMin;
-    QF_INT_UNLOCK_();
-
-    return margin;
-}
-
-// "qmp_init.cpp" ============================================================
-void QMPool::init(void *poolSto, uint32_t poolSize, QMPoolSize blockSize) {
-    // The memory block must be valid
-    // and the poolSize must fit at least one free block
-    // and the blockSize must not be too close to the top of the dynamic range
-    Q_REQUIRE((poolSto != (void *)0)
-              && (poolSize >= (uint32_t)sizeof(QFreeBlock))
-              && ((QMPoolSize)(blockSize + (QMPoolSize)sizeof(QFreeBlock))
-                    > blockSize));
-
-    m_free = poolSto;
-
-                // round up the blockSize to fit an integer number of pointers
-    m_blockSize = (QMPoolSize)sizeof(QFreeBlock);       // start with just one
-    uint32_t nblocks = (uint32_t)1;// # free blocks that fit in a memory block
-    while (m_blockSize < blockSize) {
-        m_blockSize += (QMPoolSize)sizeof(QFreeBlock);
-        ++nblocks;
-    }
-    blockSize = m_blockSize;          // use the rounded-up value from here on
-
-               // the whole pool buffer must fit at least one rounded-up block
-    Q_ASSERT(poolSize >= (uint32_t)blockSize);
-
-                                // chain all blocks together in a free-list...
-    poolSize -= (uint32_t)blockSize;             // don't chain the last block
-    m_nTot     = (QMPoolCtr)1;             // one (the last) block in the pool
-    QFreeBlock *fb = (QFreeBlock *)m_free;//start at the head of the free list
-    while (poolSize >= (uint32_t)blockSize) {
-        fb->m_next = &fb[nblocks];                      // setup the next link
-        fb = fb->m_next;                              // advance to next block
-        poolSize -= (uint32_t)blockSize;     // reduce the available pool size
-        ++m_nTot;                     // increment the number of blocks so far
-    }
-
-    fb->m_next = (QFreeBlock *)0;              // the last link points to NULL
-    m_nFree    = m_nTot;                                // all blocks are free
-    m_nMin     = m_nTot;                  // the minimum number of free blocks
-    m_start    = poolSto;               // the original start this pool buffer
-    m_end      = fb;                            // the last block in this pool
-
-    QS_INT_LOCK_KEY_
-    QS_BEGIN_(QS_QF_MPOOL_INIT, QS::mpObj_, m_start)
-        QS_OBJ_(m_start);                   // the memory managed by this pool
-        QS_MPC_(m_nTot);                         // the total number of blocks
-    QS_END_()
-}
-
-// "qmp_put.cpp" =============================================================
-void QMPool::put(void *b) {
-    //lint -e946 -e1904             ignore MISRA Rule 103 in this precondition
-    Q_REQUIRE((m_start <= b) && (b <= m_end)           /*  must be in range */
-              && (m_nFree <= m_nTot));        // # free blocks must be < total
-
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-
-    ((QFreeBlock *)b)->m_next = (QFreeBlock *)m_free;//link into the free list
-    m_free = b;                            // set as new head of the free list
-    ++m_nFree;                             // one more free block in this pool
-
-    QS_BEGIN_NOLOCK_(QS_QF_MPOOL_PUT, QS::mpObj_, m_start)
-        QS_TIME_();                                               // timestamp
-        QS_OBJ_(m_start);                   // the memory managed by this pool
-        QS_MPC_(m_nFree);             // the number of free blocks in the pool
-    QS_END_NOLOCK_()
-
-    QF_INT_UNLOCK_();
-}
-
-// "qte_arm.cpp" =============================================================
-// Package-scope objects -----------------------------------------------------
-QTimeEvt *QF_timeEvtListHead_;           // head of linked list of time events
-
-//............................................................................
-void QTimeEvt::arm_(QActive *act, QTimeEvtCtr nTicks) {
-    Q_REQUIRE((nTicks > (QTimeEvtCtr)0)          /* cannot arm with 0 ticks */
-              && (sig >= (QSignal)Q_USER_SIG)               /* valid signal */
-              && (m_prev == (QTimeEvt *)0)   /* time event must NOT be used */
-              && (act != (QActive *)0));  /* active object must be provided */
-    m_ctr = nTicks;
-    m_prev = this;                                    // mark the timer in use
-    m_act = act;
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-
-    QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_ARM, QS::teObj_, this)
-        QS_TIME_();                                               // timestamp
-        QS_OBJ_(this);                               // this time event object
-        QS_OBJ_(act);                                     // the active object
-        QS_TEC_(nTicks);                                // the number of ticks
-        QS_TEC_(m_interval);                                   // the interval
-    QS_END_NOLOCK_()
-
-    m_next = QF_timeEvtListHead_;
-    if (QF_timeEvtListHead_ != (QTimeEvt *)0) {
-        QF_timeEvtListHead_->m_prev = this;
-    }
-    QF_timeEvtListHead_ = this;
-    QF_INT_UNLOCK_();
-}
-
-// "qte_ctor.cpp" ============================================================
-QTimeEvt::QTimeEvt(QSignal s)
-  :
-#ifdef Q_EVT_CTOR
-    QEvent(s),
-#endif
-    m_prev((QTimeEvt *)0),
-    m_next((QTimeEvt *)0),
-    m_act((QActive *)0),
-    m_ctr((QTimeEvtCtr)0),
-    m_interval((QTimeEvtCtr)0)
-{
-    Q_REQUIRE(s >= (QSignal)Q_USER_SIG);                       // valid signal
-    sig = s;
-    EVT_POOL_ID(this) = (uint8_t)0;   // time event must be static, see NOTE01
-}
-
-// "qte_ctr.cpp" =============================================================
-QTimeEvtCtr QTimeEvt::ctr(void) {
-    QTimeEvtCtr ctr;
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-    if (m_prev != (QTimeEvt *)0) {        // is the time event actually armed?
-        ctr = m_ctr;
-    }
-    else {                                     // the time event was not armed
-        ctr = (QTimeEvtCtr)0;
-    }
-
-    QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_CTR, QS::teObj_, this)
-        QS_TIME_();                                               // timestamp
-        QS_OBJ_(this);                               // this time event object
-        QS_OBJ_(m_act);                                   // the active object
-        QS_TEC_(ctr);                                   // the current counter
-        QS_TEC_(m_interval);                                   // the interval
-    QS_END_NOLOCK_()
-
-    QF_INT_UNLOCK_();
-    return ctr;
-}
-
-// "qte_darm.cpp" ============================================================
-// NOTE: disarm a time evt (no harm in disarming an already disarmed time evt)
-uint8_t QTimeEvt::disarm(void) {
-    uint8_t wasArmed;
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-    if (m_prev != (QTimeEvt *)0) {        // is the time event actually armed?
-        wasArmed = (uint8_t)1;
-        if (this == QF_timeEvtListHead_) {
-            QF_timeEvtListHead_ = m_next;
-        }
-        else {
-            if (m_next != (QTimeEvt *)0) {        // not the last in the list?
-                m_next->m_prev = m_prev;
-            }
-            m_prev->m_next = m_next;
-        }
-        m_prev = (QTimeEvt *)0;             // mark the time event as disarmed
-
-        QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_DISARM, QS::teObj_, this)
-            QS_TIME_();                                           // timestamp
-            QS_OBJ_(this);                           // this time event object
-            QS_OBJ_(m_act);                               // the active object
-            QS_TEC_(m_ctr);                             // the number of ticks
-            QS_TEC_(m_interval);                               // the interval
-        QS_END_NOLOCK_()
-    }
-    else {                                     // the time event was not armed
-        wasArmed = (uint8_t)0;
-
-        QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_DISARM_ATTEMPT, QS::teObj_, this)
-            QS_TIME_();                                           // timestamp
-            QS_OBJ_(this);                           // this time event object
-            QS_OBJ_(m_act);                               // the active object
-        QS_END_NOLOCK_()
-    }
-    QF_INT_UNLOCK_();
-    return wasArmed;
-}
-
-// "qte_rarm.cpp" ============================================================
-uint8_t QTimeEvt::rearm(QTimeEvtCtr nTicks) {
-    Q_REQUIRE((nTicks > (QTimeEvtCtr)0)        /* cannot rearm with 0 ticks */
-              && (sig >= (QSignal)Q_USER_SIG)               /* valid signal */
-              && (m_act != (QActive *)0));              // valid active object
-    uint8_t isArmed;
-    QF_INT_LOCK_KEY_
-    QF_INT_LOCK_();
-    m_ctr = nTicks;
-    if (m_prev == (QTimeEvt *)0) {             // is this time event disarmed?
-        isArmed = (uint8_t)0;
-        m_next = QF_timeEvtListHead_;
-        if (QF_timeEvtListHead_ != (QTimeEvt *)0) {
-            QF_timeEvtListHead_->m_prev = this;
-        }
-        QF_timeEvtListHead_ = this;
-        m_prev = this;                             // mark the time evt in use
-    }
-    else {                                          // the time event is armed
-        isArmed = (uint8_t)1;
-    }
-
-    QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_REARM, QS::teObj_, this)
-        QS_TIME_();                                               // timestamp
-        QS_OBJ_(this);                               // this time event object
-        QS_OBJ_(m_act);                                   // the active object
-        QS_TEC_(m_ctr);                                 // the number of ticks
-        QS_TEC_(m_interval);                                   // the interval
-        QS_U8_(isArmed);                               // was the timer armed?
-    QS_END_NOLOCK_()
-
-    QF_INT_UNLOCK_();
-    return isArmed;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Kernel selection based on QK_PREEMPTIVE
-//
-#ifdef QK_PREEMPTIVE
-
-// "qk_pkg.h" ================================================================
-                                    // QK internal interrupt locking/unlocking
-#ifndef QF_INT_KEY_TYPE
-    #define QK_INT_LOCK_KEY_
-    #define QK_INT_LOCK_()      QF_INT_LOCK(dummy)
-    #define QK_INT_UNLOCK_()    QF_INT_UNLOCK(dummy)
-#else
-
-    /// \brief This is an internal macro for defining the interrupt lock key.
-    ///
-    /// The purpose of this macro is to enable writing the same code for the
-    /// case when interrupt key is defined and when it is not. If the macro
-    /// #QF_INT_KEY_TYPE is defined, this internal macro provides the
-    /// definition of the lock key variable. Otherwise this macro is empty.
-    /// \sa #QF_INT_KEY_TYPE, #QF_INT_LOCK_, #QF_INT_UNLOCK_
-    #define QK_INT_LOCK_KEY_    QF_INT_KEY_TYPE intLockKey_;
-
-    /// \brief This is an internal macro for locking interrupts.
-    ///
-    /// The purpose of this macro is to enable writing the same code for the
-    /// case when interrupt key is defined and when it is not. If the macro
-    /// #QF_INT_KEY_TYPE is defined, this internal macro invokes #QF_INT_LOCK
-    /// passing the key variable as the parameter. Otherwise #QF_INT_LOCK
-    /// is invoked with a dummy parameter.
-    /// \sa #QK_INT_LOCK_KEY_, #QK_INT_UNLOCK_
-    #define QK_INT_LOCK_()      QF_INT_LOCK(intLockKey_)
-
-    /// \brief This is an internal macro for unlocking interrupts.
-    ///
-    /// The purpose of this macro is to enable writing the same code for the
-    /// case when interrupt key is defined and when it is not. If the macro
-    /// #QF_INT_KEY_TYPE is defined, this internal macro invokes
-    /// #QF_INT_UNLOCK passing the key variable as the parameter. Otherwise
-    /// #QF_INT_UNLOCK is invoked with a dummy parameter.
-    /// \sa #QK_INT_LOCK_KEY_, #QK_INT_LOCK_
-    #define QK_INT_UNLOCK_()    QF_INT_UNLOCK(intLockKey_)
-#endif
-
-                                                   // package-scope objects...
-#ifndef QK_NO_MUTEX
-    extern uint8_t volatile QK_ceilingPrio_;    ///< QK mutex priority ceiling
-#endif
-
-// "qk.cpp" ==================================================================
-
-// Public-scope objects ------------------------------------------------------
-#if (QF_MAX_ACTIVE <= 8U)
-#ifdef Q_USE_NAMESPACE
-    QP::QPSet8  volatile QK_readySet_;                      // ready set of QK
-#else
-    QPSet8  volatile QK_readySet_;                          // ready set of QK
-#endif
-#else
-#ifdef Q_USE_NAMESPACE
-    QP::QPSet64 volatile QK_readySet_;                      // ready set of QK
-#else
-    QPSet64 volatile QK_readySet_;                          // ready set of QK
-#endif
-#endif
-
-#ifdef Q_USE_NAMESPACE
-}                                                              // namespace QP
-#endif
-                                         // start with the QK scheduler locked
-extern "C" {
-
-uint8_t volatile QK_currPrio_ = (uint8_t)(QF_MAX_ACTIVE + 1);
-uint8_t volatile QK_intNest_;                 // start with nesting level of 0
-
-}                                                                // extern "C"
-
-#ifdef Q_USE_NAMESPACE
-namespace QP {
-#endif
-
-//............................................................................
-//lint -e970 -e971               ignore MISRA rules 13 and 14 in this function
-char const Q_ROM * Q_ROM_VAR QK::getVersion(void) {
-    static char const Q_ROM Q_ROM_VAR version[] = {
-        (char)(((QP_VERSION >> 12U) & 0xFU) + (uint8_t)'0'),
-        '.',
-        (char)(((QP_VERSION >>  8U) & 0xFU) + (uint8_t)'0'),
-        '.',
-        (char)(((QP_VERSION >>  4U) & 0xFU) + (uint8_t)'0'),
-        (char)((QP_VERSION          & 0xFU) + (uint8_t)'0'),
-        '\0'
-    };
-    return version;
-}
-//............................................................................
-void QF::init(void) {
-    QK_init();           // QK initialization ("C" linkage, might be assembly)
-}
-//............................................................................
-void QF::stop(void) {
-    QF::onCleanup();                                       // cleanup callback
-    // nothing else to do for the QK preemptive kernel
-}
-//............................................................................
-void QF::run(void) {
-    QK_INT_LOCK_KEY_
-
-    QK_INT_LOCK_();
-    QK_currPrio_ = (uint8_t)0;        // set the priority for the QK idle loop
-    QK_SCHEDULE_();                      // process all events produced so far
-    QK_INT_UNLOCK_();
-
-    QF::onStartup();                                       // startup callback
-
-    for (;;) {                                             // the QK idle loop
-        QK::onIdle();                        // invoke the QK on-idle callback
-    }
-}
-//............................................................................
-void QActive::start(uint8_t prio,
-                    QEvent const *qSto[], uint32_t qLen,
-                    void *tls, uint32_t flags,
-                    QEvent const *ie)
-{
-    Q_REQUIRE(((uint8_t)0 < prio) && (prio <= (uint8_t)QF_MAX_ACTIVE));
-
-    m_eQueue.init(qSto, (QEQueueCtr)qLen);       // initialize the event queue
-    m_prio = prio;
-    QF::add_(this);                     // make QF aware of this active object
-
-#if defined(QK_TLS) || defined(QK_EXT_SAVE)
-    m_osObject = (uint8_t)flags;       // m_osObject contains the thread flags
-    m_thread   = tls;      // contains the pointer to the thread-local-storage
-#else
-    Q_ASSERT((tls == (void *)0) && (flags == (uint32_t)0));
-#endif
-
-    init(ie);                                    // execute initial transition
-
-    QS_FLUSH();                          // flush the trace buffer to the host
-}
-//............................................................................
-void QActive::stop(void) {
-    QF::remove_(this);                // remove this active object from the QF
-}
-
-// "qk_sched" ================================================================
-
-#ifdef Q_USE_NAMESPACE
-}                                                              // namespace QP
-#endif
-
-//............................................................................
-// NOTE: the QK scheduler is entered and exited with interrupts LOCKED.
-// QK_schedule_() is extern "C", so it does not belong to the QP namespace.
-//
-extern "C" {
-
-#ifndef QF_INT_KEY_TYPE
-void QK_schedule_(void) {
-#else
-void QK_schedule_(QF_INT_KEY_TYPE intLockKey_) {
-#endif
-
-#ifdef Q_USE_NAMESPACE
-    using namespace QP;
-#endif
-                         // the QK scheduler must be called at task level only
-    Q_REQUIRE(QK_intNest_ == (uint8_t)0);
-
-           // determine the priority of the highest-priority task ready to run
-    uint8_t p = QK_readySet_.findMax();
-
-#ifdef QK_NO_MUTEX
-    if (p > QK_currPrio_) {                        // do we have a preemption?
-#else                                   // QK priority-ceiling mutexes allowed
-    if ((p > QK_currPrio_) && (p > QK_ceilingPrio_)) {
-#endif
-        uint8_t pin = QK_currPrio_;               // save the initial priority
-        QActive *a;
-#ifdef QK_TLS                                    // thread-local storage used?
-        uint8_t pprev = pin;
-#endif
-        do {
-            QEvent const *e;
-            a = QF::active_[p];                // obtain the pointer to the AO
-            QK_currPrio_ = p;        // this becomes the current task priority
-
-#ifdef QK_TLS                                    // thread-local storage used?
-            if (p != pprev) {                      // are we changing threads?
-                QK_TLS(a);                  // switch new thread-local storage
-                pprev = p;
-            }
-#endif
-            QS_BEGIN_NOLOCK_(QS_QK_SCHEDULE, QS::aoObj_, a)
-                QS_TIME_();                                       // timestamp
-                QS_U8_(p);                // the priority of the active object
-                QS_U8_(pin);                         // the preempted priority
-            QS_END_NOLOCK_()
-
-            QK_INT_UNLOCK_();                         // unlock the interrupts
-
-            e = a->get_();        // get the next event for this active object
-            a->dispatch(e);                 // dispatch e to the active object
-            QF::gc(e);              // garbage collect the event, if necessary
-
-            QK_INT_LOCK_();
-                             // determine the highest-priority AO ready to run
-            if (QK_readySet_.notEmpty()) {
-                p = QK_readySet_.findMax();
-            }
-            else {
-                p = (uint8_t)0;
-            }
-#ifdef QK_NO_MUTEX
-        } while (p > pin);         // is the new priority higher than initial?
-#else                                   // QK priority-ceiling mutexes allowed
-        } while ((p > pin) && (p > QK_ceilingPrio_));
-#endif
-        QK_currPrio_ = pin;                    // restore the initial priority
-
-#ifdef QK_TLS                                    // thread-local storage used?
-        if (pin != (uint8_t)0) {      // no extended context for the idle loop
-            a = QF::active_[pin];           // the pointer to the preempted AO
-            QK_TLS(a);                             // restore the original TLS
-        }
-#endif
-    }
-}
-
-}                                                                // extern "C"
-
-#ifdef Q_USE_NAMESPACE
-namespace QP {
-#endif
-
-// "qk_mutex.cpp" ============================================================
-#ifndef QK_NO_MUTEX
-
-// package-scope objects -----------------------------------------------------
-uint8_t volatile QK_ceilingPrio_;               // ceiling priority of a mutex
-
-//............................................................................
-QMutex QK::mutexLock(uint8_t prioCeiling) {
-    QK_INT_LOCK_KEY_
-    QK_INT_LOCK_();
-    uint8_t mutex = QK_ceilingPrio_; // original QK priority ceiling to return
-    if (QK_ceilingPrio_ < prioCeiling) {
-        QK_ceilingPrio_ = prioCeiling;        // raise the QK priority ceiling
-    }
-
-    QS_BEGIN_NOLOCK_(QS_QK_MUTEX_LOCK, (void *)0, (void *)0)
-        QS_TIME_();                                               // timestamp
-        QS_U8_(mutex);                                // the original priority
-        QS_U8_(QK_ceilingPrio_);               // the current priority ceiling
-    QS_END_NOLOCK_()
-
-    QK_INT_UNLOCK_();
-    return mutex;
-}
-//............................................................................
-void QK::mutexUnlock(QMutex mutex) {
-    QK_INT_LOCK_KEY_
-    QK_INT_LOCK_();
-
-    QS_BEGIN_NOLOCK_(QS_QK_MUTEX_UNLOCK, (void *)0, (void *)0)
-        QS_TIME_();                                               // timestamp
-        QS_U8_(mutex);                                // the original priority
-        QS_U8_(QK_ceilingPrio_);               // the current priority ceiling
-    QS_END_NOLOCK_()
-
-    if (QK_ceilingPrio_ > mutex) {
-        QK_ceilingPrio_ = mutex;         // restore the saved priority ceiling
-        QK_SCHEDULE_();
-    }
-    QK_INT_UNLOCK_();
-}
-#endif                                                          // QK_NO_MUTEX
-
-#else                                                         // QK_PREEMPTIVE
-
-// "qvanilla.cpp" ============================================================
-// Package-scope objects -----------------------------------------------------
-#if (QF_MAX_ACTIVE <= 8)
-    QPSet8  volatile QF_readySet_;           // QF-ready set of active objects
-#else
-    QPSet64 volatile QF_readySet_;           // QF-ready set of active objects
-#endif
-
-//............................................................................
-char const Q_ROM * Q_ROM_VAR QF::getPortVersion(void) {
-    static const char Q_ROM version[] = "4.0.00";
-    return version;
-}
-//............................................................................
-void QF::init(void) {
-    // nothing to do for the "vanilla" kernel
-}
-//............................................................................
-void QActive::start(uint8_t prio,
-                    QEvent const *qSto[], uint32_t qLen,
-                    void *stkSto, uint32_t /*lint -e1904 stkSize */,
-                    QEvent const *ie)
-{
-    Q_REQUIRE(((uint8_t)0 < prio) && (prio <= (uint8_t)QF_MAX_ACTIVE)
-              && (stkSto == (void *)0));      // does not need per-actor stack
-
-    m_eQueue.init(qSto, (QEQueueCtr)qLen);               // initialize QEQueue
-    m_prio = prio;                // set the QF priority of this active object
-    QF::add_(this);                     // make QF aware of this active object
-    init(ie);                                    // execute initial transition
-
-    QS_FLUSH();                          // flush the trace buffer to the host
-}
-//............................................................................
-void QActive::stop(void) {
-    QF::remove_(this);
-}
-
-//............................................................................
-void QF::stop(void) {
-    QF::onCleanup();                                       // cleanup callback
-    // nothing else to do for the "vanilla" kernel
-}
-//............................................................................
-void QF::run(void) {
-    QF::onStartup();                                       // startup callback
-
-    for (;;) {                                           // the bacground loop
-        QF_INT_LOCK_KEY_
-        QF_INT_LOCK_();
-        if (QF_readySet_.notEmpty()) {
-            uint8_t p = QF_readySet_.findMax();
-            QActive *a = active_[p];
-            QF_INT_UNLOCK_();
-
-            QEvent const *e = a->get_();     // get the next event for this AO
-            a->dispatch(e);                         // dispatch evt to the HSM
-            gc(e);       // determine if event is garbage and collect it if so
-        }
-        else {
-#ifndef QF_INT_KEY_TYPE
-            onIdle();                                            // see NOTE01
-#else
-            onIdle(intLockKey_);                                 // see NOTE01
-#endif                                                      // QF_INT_KEY_TYPE
-        }
-    }
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// NOTE01:
-// QF::onIdle() must be called with interrupts LOCKED because the
-// determination of the idle condition (no events in the queues) can change
-// at any time by an interrupt posting events to a queue. The QF::onIdle()
-// MUST enable interrups internally, perhaps at the same time as putting the
-// CPU into a power-saving mode.
-//
-
-#endif                                                        // QK_PREEMPTIVE
-
-//////////////////////////////////////////////////////////////////////////////
-#ifdef Q_SPY
-
-// "qs_pkg.h" ================================================================
-/// \brief QS ring buffer counter and offset type
-typedef uint16_t QSCtr;
-
-/// \brief Internal QS macro to insert an un-escaped byte into
-/// the QS buffer
-////
-#define QS_INSERT_BYTE(b_) \
-    QS_ring_[QS_head_] = (b_); \
-    ++QS_head_; \
-    if (QS_head_ == QS_end_) { \
-        QS_head_ = (QSCtr)0; \
-    } \
-    ++QS_used_;
-
-/// \brief Internal QS macro to insert an escaped byte into the QS buffer
-#define QS_INSERT_ESC_BYTE(b_) \
-    QS_chksum_ = (uint8_t)(QS_chksum_ + (b_)); \
-    if (((b_) == QS_FRAME) || ((b_) == QS_ESC)) { \
-        QS_INSERT_BYTE(QS_ESC) \
-        QS_INSERT_BYTE((uint8_t)((b_) ^ QS_ESC_XOR)) \
-    } \
-    else { \
-        QS_INSERT_BYTE(b_) \
-    }
-
-/// \brief Internal QS macro to insert a escaped checksum byte into
-/// the QS buffer
-#define QS_INSERT_CHKSUM_BYTE() \
-    QS_chksum_ = (uint8_t)~QS_chksum_; \
-    if ((QS_chksum_ == QS_FRAME) || (QS_chksum_ == QS_ESC)) { \
-        QS_INSERT_BYTE(QS_ESC) \
-        QS_INSERT_BYTE((uint8_t)(QS_chksum_ ^ QS_ESC_XOR)) \
-    } \
-    else { \
-        QS_INSERT_BYTE(QS_chksum_) \
-    }
-
-
-/// \brief Frame character of the QS output protocol
-#define QS_FRAME    ((uint8_t)0x7E)
-
-/// \brief Escape character of the QS output protocol
-#define QS_ESC      ((uint8_t)0x7D)
-
-/// \brief Escape modifier of the QS output protocol
-///
-/// The escaped byte is XOR-ed with the escape modifier before it is inserted
-/// into the QS buffer.
-#define QS_ESC_XOR  0x20
-
-#ifndef Q_ROM_BYTE
-    /// \brief Macro to access a byte allocated in ROM
-    ///
-    /// Some compilers for Harvard-architecture MCUs, such as gcc for AVR, do
-    /// not generate correct code for accessing data allocated in the program
-    /// space (ROM). The workaround for such compilers is to explictly add
-    /// assembly code to access each data element allocated in the program
-    /// space. The macro Q_ROM_BYTE() retrieves a byte from the given ROM
-    /// address.
-    ///
-    /// The Q_ROM_BYTE() macro should be defined for the compilers that
-    /// cannot handle correctly data allocated in ROM (such as the gcc).
-    /// If the macro is left undefined, the default definition simply returns
-    /// the argument and lets the compiler generate the correct code.
-    #define Q_ROM_BYTE(rom_var_)   (rom_var_)
-#endif
-
-//............................................................................
-extern uint8_t *QS_ring_;         ///< pointer to the start of the ring buffer
-extern QSCtr QS_end_;                ///< offset of the end of the ring buffer
-extern QSCtr QS_head_;         ///< offset to where next byte will be inserted
-extern QSCtr QS_tail_;       ///< offset of where next event will be extracted
-extern QSCtr QS_used_;       ///< number of bytes currently in the ring buffer
-extern uint8_t QS_seq_;                        ///< the record sequence number
-extern uint8_t QS_chksum_;             ///< the checksum of the current record
-extern uint8_t QS_full_;              ///< the ring buffer is temporarily full
-
-// "qs.cpp" ==================================================================
-//............................................................................
-uint8_t QS::glbFilter_[32];                                // global QS filter
-
-//............................................................................
-uint8_t *QS_ring_;                  // pointer to the start of the ring buffer
-QSCtr QS_end_;                         // offset of the end of the ring buffer
-QSCtr QS_head_;                  // offset to where next byte will be inserted
-QSCtr QS_tail_;                 // offset of where next byte will be extracted
-QSCtr QS_used_;                // number of bytes currently in the ring buffer
-uint8_t QS_seq_;                                 // the record sequence number
-uint8_t QS_chksum_;                      // the checksum of the current record
-uint8_t QS_full_;                       // the ring buffer is temporarily full
-
-//............................................................................
-//lint -e970 -e971               ignore MISRA rules 13 and 14 in this function
-char const Q_ROM * Q_ROM_VAR QS::getVersion(void) {
-    static char const Q_ROM Q_ROM_VAR version[] = {
-        (char)(((QP_VERSION >> 12U) & 0xFU) + (uint8_t)'0'),
-        '.',
-        (char)(((QP_VERSION >>  8U) & 0xFU) + (uint8_t)'0'),
-        '.',
-        (char)(((QP_VERSION >>  4U) & 0xFU) + (uint8_t)'0'),
-        (char)((QP_VERSION          & 0xFU) + (uint8_t)'0'),
-        '\0'
-    };
-    return version;
-}
-//............................................................................
-void QS::initBuf(uint8_t sto[], uint32_t stoSize) {
-    QS_ring_ = &sto[0];
-    QS_end_  = (QSCtr)stoSize;
-}
-//............................................................................
-void QS::filterOn(uint8_t rec) {
-    if (rec == QS_ALL_RECORDS) {
-        uint8_t i;
-        for (i = (uint8_t)0; i < (uint8_t)sizeof(glbFilter_); ++i) {
-            glbFilter_[i] = (uint8_t)0xFF;
-        }
-    }
-    else {
-        glbFilter_[rec >> 3] |= (uint8_t)(1U << (rec & 0x07));
-    }
-}
-//............................................................................
-void QS::filterOff(uint8_t rec) {
-    if (rec == QS_ALL_RECORDS) {
-        uint8_t i;
-        for (i = (uint8_t)0; i < (uint8_t)sizeof(glbFilter_); ++i) {
-            glbFilter_[i] = (uint8_t)0;
-        }
-    }
-    else {
-        glbFilter_[rec >> 3] &= (uint8_t)(~(1U << (rec & 0x07)));
-    }
-}
-//............................................................................
-void QS::begin(uint8_t rec) {
-    QS_chksum_ = (uint8_t)0;                             // clear the checksum
-    ++QS_seq_;                         // always increment the sequence number
-    QS_INSERT_ESC_BYTE(QS_seq_)                   // store the sequence number
-    QS_INSERT_ESC_BYTE(rec)                             // store the record ID
-}
-//............................................................................
-void QS::end(void) {
-    QS_INSERT_CHKSUM_BYTE()
-    QS_INSERT_BYTE(QS_FRAME)
-    if (QS_used_ > QS_end_) {                    // overrun over the old data?
-        QS_tail_ = QS_head_;                 // shift the tail to the old data
-        QS_used_ = QS_end_;                        // the whole buffer is used
-    }
-}
-//............................................................................
-void QS::u8(uint8_t format, uint8_t d) {
-    QS_INSERT_ESC_BYTE(format)
-    QS_INSERT_ESC_BYTE(d)
-}
-//............................................................................
-void QS::u16(uint8_t format, uint16_t d) {
-    QS_INSERT_ESC_BYTE(format)
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-    d >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-}
-//............................................................................
-void QS::u32(uint8_t format, uint32_t d) {
-    QS_INSERT_ESC_BYTE(format)
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-    d >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-    d >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-    d >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-}
-
-// "qs_.cpp" =================================================================
-//............................................................................
-void const *QS::smObj_;                  // local state machine for QEP filter
-void const *QS::aoObj_;                   // local active object for QF filter
-void const *QS::mpObj_;                     //  local event pool for QF filter
-void const *QS::eqObj_;                      //  local raw queue for QF filter
-void const *QS::teObj_;                     //  local time event for QF filter
-void const *QS::apObj_;                    //  local object Application filter
-
-QSTimeCtr volatile QS::tickCtr_;     // tick counter for the QS_QF_TICK record
-
-//............................................................................
-void QS::u8_(uint8_t d) {
-    QS_INSERT_ESC_BYTE(d)
-}
-//............................................................................
-void QS::u16_(uint16_t d) {
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-    d >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-}
-//............................................................................
-void QS::u32_(uint32_t d) {
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-    d >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-    d >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-    d >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-}
-//............................................................................
-//lint -e970 -e971               ignore MISRA rules 13 and 14 in this function
-void QS::str_(char const *s) {
-    while (*s != '\0') {
-                                       // ASCII characters don't need escaping
-        QS_chksum_ = (uint8_t)(QS_chksum_ + (uint8_t)(*s));
-        QS_INSERT_BYTE((uint8_t)(*s))
-        ++s;
-    }
-    QS_INSERT_BYTE((uint8_t)0)
-}
-//............................................................................
-//lint -e970 -e971               ignore MISRA rules 13 and 14 in this function
-void QS::str_ROM_(char const Q_ROM * Q_ROM_VAR s) {
-    uint8_t b;
-    while ((b = (uint8_t)Q_ROM_BYTE(*s)) != (uint8_t)0) {
-                                       // ASCII characters don't need escaping
-        QS_chksum_ = (uint8_t)(QS_chksum_ + b);
-        QS_INSERT_BYTE(b)
-        ++s;
-    }
-    QS_INSERT_BYTE((uint8_t)0)
-}
-
-// "qs_blk.cpp" ==============================================================
-//............................................................................
-// get up to *pn bytes of contiguous memory
-uint8_t const *QS::getBlock(uint16_t *pNbytes) {
-    uint8_t *block;
-    if (QS_used_ == (QSCtr)0) {
-        *pNbytes = (uint16_t)0;
-        block = (uint8_t *)0;                  // no bytes to return right now
-    }
-    else {
-        QSCtr n = (QSCtr)(QS_end_ - QS_tail_);
-        if (n > QS_used_) {
-            n = QS_used_;
-        }
-        if (n > (QSCtr)(*pNbytes)) {
-            n = (QSCtr)(*pNbytes);
-        }
-        *pNbytes = (uint16_t)n;
-        QS_used_ = (QSCtr)(QS_used_ - n);
-        QSCtr t  = QS_tail_;
-        QS_tail_ = (QSCtr)(QS_tail_ + n);
-        if (QS_tail_ == QS_end_) {
-            QS_tail_ = (QSCtr)0;
-        }
-        block = &QS_ring_[t];
-    }
-    return block;
-}
-
-// "qs_byte.cpp" =============================================================
-//............................................................................
-uint16_t QS::getByte(void) {
-    uint16_t ret;
-    if (QS_used_ == (QSCtr)0) {
-        ret = QS_EOD;                                       // set End-Of-Data
-    }
-    else {
-        ret = QS_ring_[QS_tail_];                    // set the byte to return
-        ++QS_tail_;                                        // advance the tail
-        if (QS_tail_ == QS_end_) {                        // tail wrap around?
-            QS_tail_ = (QSCtr)0;
-        }
-        --QS_used_;                                      // one less byte used
-    }
-    return ret;                                      // return the byte or EOD
-}
-
-// "qs_f32.cpp" ==============================================================
-//............................................................................
-void QS::f32(uint8_t format, float f) {
-    union F32Rep {
-        float f;
-        uint32_t u;
-    } fu32;
-    fu32.f = f;
-
-    QS_INSERT_ESC_BYTE(format)
-    QS_INSERT_ESC_BYTE((uint8_t)fu32.u)
-    fu32.u >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)fu32.u)
-    fu32.u >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)fu32.u)
-    fu32.u >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)fu32.u)
-}
-
-// "qs_f64.cpp" ==============================================================
-//............................................................................
-void QS::f64(uint8_t format, double d) {
-    union F64Rep {
-        double d;
-        struct UInt2 {
-            uint32_t u1, u2;
-        } i;
-    } fu64;
-    fu64.d = d;
-
-    QS_INSERT_ESC_BYTE(format)
-
-    QS_INSERT_ESC_BYTE((uint8_t)fu64.i.u1)
-    fu64.i.u1 >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)fu64.i.u1)
-    fu64.i.u1 >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)fu64.i.u1)
-    fu64.i.u1 >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)fu64.i.u1)
-
-    QS_INSERT_ESC_BYTE((uint8_t)fu64.i.u2)
-    fu64.i.u2 >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)fu64.i.u2)
-    fu64.i.u2 >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)fu64.i.u2)
-    fu64.i.u2 >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)fu64.i.u2)
-}
-
-// "qs_mem.cpp" ==============================================================
-//............................................................................
-void QS::mem(uint8_t const *blk, uint8_t size) {
-    QS_INSERT_BYTE((uint8_t)QS_MEM_T)
-    QS_chksum_ = (uint8_t)(QS_chksum_ + (uint8_t)QS_MEM_T);
-    QS_INSERT_ESC_BYTE(size)
-    while (size != (uint8_t)0) {
-        QS_INSERT_ESC_BYTE(*blk)
-        ++blk;
-        --size;
-    }
-}
-
-// "qs_str.cpp" ==============================================================
-//............................................................................
-//lint -e970 -e971               ignore MISRA rules 13 and 14 in this function
-void QS::str(char const *s) {
-    QS_INSERT_BYTE((uint8_t)QS_STR_T)
-    QS_chksum_ = (uint8_t)(QS_chksum_ + (uint8_t)QS_STR_T);
-    while ((*s) != '\0') {
-                                       // ASCII characters don't need escaping
-        QS_INSERT_BYTE((uint8_t)(*s))
-        QS_chksum_ = (uint8_t)(QS_chksum_ + (uint8_t)(*s));
-        ++s;
-    }
-    QS_INSERT_BYTE((uint8_t)0)
-}
-//............................................................................
-//lint -e970 -e971               ignore MISRA rules 13 and 14 in this function
-void QS::str_ROM(char const Q_ROM * Q_ROM_VAR s) {
-    QS_INSERT_BYTE((uint8_t)QS_STR_T)
-    QS_chksum_ = (uint8_t)(QS_chksum_ + (uint8_t)QS_STR_T);
-    uint8_t b;
-    while ((b = (uint8_t)Q_ROM_BYTE(*s)) != (uint8_t)0) {
-                                       // ASCII characters don't need escaping
-        QS_INSERT_BYTE(b)
-        QS_chksum_ = (uint8_t)(QS_chksum_ + b);
-        ++s;
-    }
-    QS_INSERT_BYTE((uint8_t)0)
-}
-
-// "qs_u64.cpp" ==============================================================
-#if (QS_OBJ_PTR_SIZE == 8) || (QS_FUN_PTR_SIZE == 8)
-
-//............................................................................
-void QS::u64_(uint64_t d) {
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-    d >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-    d >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-    d >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-    d >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-    d >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-    d >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-    d >>= 8;
-    QS_INSERT_ESC_BYTE((uint8_t)d)
-}
-//............................................................................
-void QS::u64(uint8_t format, uint64_t d) {
-    QS_INSERT_ESC_BYTE(format)
-    u64_(d);
-}
-
-#endif
-
-#endif                                                                // Q_SPY
-
-#ifdef Q_USE_NAMESPACE
-}                                                              // namespace QP
-#endif
-
+//////////////////////////////////////////////////////////////////////////////
+// Product: QP/C++
+// Last Updated for QP ver: 4.5.02 (modified to fit in one file)
+// Date of the Last Update: Aug 24, 2012
+//
+//                    Q u a n t u m     L e a P s
+//                    ---------------------------
+//                    innovating embedded systems
+//
+// Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved.
+//
+// This program is open source software: you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as published
+// by the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// Alternatively, this program may be distributed and modified under the
+// terms of Quantum Leaps commercial licenses, which expressly supersede
+// the GNU General Public License and are specifically designed for
+// licensees interested in retaining the proprietary status of their code.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+// Contact information:
+// Quantum Leaps Web sites: http://www.quantum-leaps.com
+//                          http://www.state-machine.com
+// e-mail:                  info@quantum-leaps.com
+//////////////////////////////////////////////////////////////////////////////
+#include "qp_port.h"                                                // QP port
+
+// "qep_pkg.h" ===============================================================
+QP_BEGIN_
+
+Q_DEFINE_THIS_MODULE("qp")
+
+//////////////////////////////////////////////////////////////////////////////
+/// preallocated reserved events
+extern QEvt const QEP_reservedEvt_[];
+
+/// empty signal for internal use only
+QSignal const QEP_EMPTY_SIG_ = static_cast<QSignal>(0);
+
+/// maximum depth of state nesting (including the top level), must be >= 3
+int8_t const QEP_MAX_NEST_DEPTH_ = static_cast<int8_t>(6);
+
+uint8_t const u8_0  = static_cast<uint8_t>(0); ///< \brief constant (uint8_t)0
+uint8_t const u8_1  = static_cast<uint8_t>(1); ///< \brief constant (uint8_t)1
+int8_t  const s8_0  = static_cast<int8_t>(0);  ///< \brief constant  (int8_t)0
+int8_t  const s8_1  = static_cast<int8_t>(1);  ///< \brief constant  (int8_t)1
+int8_t  const s8_n1 = static_cast<int8_t>(-1); ///< \brief constant (int8_t)-1
+
+QP_END_
+
+/// helper macro to trigger internal event in an HSM
+#define QEP_TRIG_(state_, sig_) \
+    ((*(state_))(this, &QEP_reservedEvt_[sig_]))
+
+/// helper macro to trigger exit action in an HSM
+#define QEP_EXIT_(state_) do { \
+    if (QEP_TRIG_(state_, Q_EXIT_SIG) == Q_RET_HANDLED) { \
+        QS_BEGIN_(QS_QEP_STATE_EXIT, QS::smObj_, this) \
+            QS_OBJ_(this); \
+            QS_FUN_(state_); \
+        QS_END_() \
+    } \
+} while (false)
+
+/// helper macro to trigger entry action in an HSM
+#define QEP_ENTER_(state_) do { \
+    if (QEP_TRIG_(state_, Q_ENTRY_SIG) == Q_RET_HANDLED) { \
+        QS_BEGIN_(QS_QEP_STATE_ENTRY, QS::smObj_, this) \
+            QS_OBJ_(this); \
+            QS_FUN_(state_); \
+        QS_END_() \
+    } \
+} while (false)
+
+// "qep.cpp" =================================================================
+/// \brief ::QEP_reservedEvt_ definition and QEP::getVersion() implementation.
+
+QP_BEGIN_
+
+// Package-scope objects -----------------------------------------------------
+QEvt const QEP_reservedEvt_[] = {
+#ifdef Q_EVT_CTOR                         // Is the QEvt constructor provided?
+    static_cast<QSignal>(0),
+    static_cast<QSignal>(1),
+    static_cast<QSignal>(2),
+    static_cast<QSignal>(3)
+#else                                    // QEvt is a POD (Plain Old Datatype)
+    { static_cast<QSignal>(0), u8_0, u8_0 },
+    { static_cast<QSignal>(1), u8_0, u8_0 },
+    { static_cast<QSignal>(2), u8_0, u8_0 },
+    { static_cast<QSignal>(3), u8_0, u8_0 }
+#endif
+};
+//............................................................................
+char_t const Q_ROM * Q_ROM_VAR QEP::getVersion(void) {
+    uint8_t const u8_zero = static_cast<uint8_t>('0');
+    static char_t const Q_ROM Q_ROM_VAR version[] = {
+        static_cast<char_t>(((QP_VERSION >> 12) & 0xFU) + u8_zero),
+        static_cast<char_t>('.'),
+        static_cast<char_t>(((QP_VERSION >>  8) & 0xFU) + u8_zero),
+        static_cast<char_t>('.'),
+        static_cast<char_t>(((QP_VERSION >>  4) & 0xFU) + u8_zero),
+        static_cast<char_t>((QP_VERSION         & 0xFU) + u8_zero),
+        static_cast<char_t>('\0')
+    };
+    return version;
+}
+
+QP_END_
+
+// "qhsm_top.cpp" ============================================================
+/// \brief QHsm::top() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+QState QHsm::top(void * const, QEvt const * const) {
+    return Q_RET_IGNORED;                  // the top state ignores all events
+}
+
+QP_END_
+
+// "qhsm_ini.cpp" ============================================================
+/// \brief QHsm::init() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+QHsm::~QHsm() {
+}
+//............................................................................
+void QHsm::init(QEvt const * const e) {
+    QStateHandler t = m_state;
+
+    Q_REQUIRE((m_temp != Q_STATE_CAST(0))             // ctor must be executed
+              && (t == Q_STATE_CAST(&QHsm::top)));  // initial tran. NOT taken
+
+                              // the top-most initial transition must be taken
+    Q_ALLEGE((*m_temp)(this, e) == Q_RET_TRAN);
+
+    QS_CRIT_STAT_
+    do {                                           // drill into the target...
+        QStateHandler path[QEP_MAX_NEST_DEPTH_];
+        int8_t ip = s8_0;                       // transition entry path index
+
+        QS_BEGIN_(QS_QEP_STATE_INIT, QS::smObj_, this)
+            QS_OBJ_(this);                        // this state machine object
+            QS_FUN_(t);                                    // the source state
+            QS_FUN_(m_temp);           // the target of the initial transition
+        QS_END_()
+
+        path[0] = m_temp;
+        (void)QEP_TRIG_(m_temp, QEP_EMPTY_SIG_);
+        while (m_temp != t) {
+            ++ip;
+            path[ip] = m_temp;
+            (void)QEP_TRIG_(m_temp, QEP_EMPTY_SIG_);
+        }
+        m_temp = path[0];
+                                               // entry path must not overflow
+        Q_ASSERT(ip < QEP_MAX_NEST_DEPTH_);
+
+        do {           // retrace the entry path in reverse (desired) order...
+            QEP_ENTER_(path[ip]);                            // enter path[ip]
+            --ip;
+        } while (ip >= s8_0);
+
+        t = path[0];                   // current state becomes the new source
+    } while (QEP_TRIG_(t, Q_INIT_SIG) == Q_RET_TRAN);
+
+    QS_BEGIN_(QS_QEP_INIT_TRAN, QS::smObj_, this)
+        QS_TIME_();                                              // time stamp
+        QS_OBJ_(this);                            // this state machine object
+        QS_FUN_(t);                                    // the new active state
+    QS_END_()
+
+    m_state = t;                            // change the current active state
+    m_temp  = t;                           // mark the configuration as stable
+}
+
+QP_END_
+
+// "qhsm_dis.cpp" ============================================================
+/// \brief QHsm::dispatch() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+void QHsm::dispatch(QEvt const * const e) {
+    QStateHandler t = m_state;
+
+    Q_REQUIRE(t == m_temp);          // the state configuration must be stable
+
+    QStateHandler s;
+    QState r;
+    QS_CRIT_STAT_
+
+    QS_BEGIN_(QS_QEP_DISPATCH, QS::smObj_, this)
+        QS_TIME_();                                              // time stamp
+        QS_SIG_(e->sig);                            // the signal of the event
+        QS_OBJ_(this);                            // this state machine object
+        QS_FUN_(t);                                       // the current state
+    QS_END_()
+
+    do {                                // process the event hierarchically...
+        s = m_temp;
+        r = (*s)(this, e);                           // invoke state handler s
+
+        if (r == Q_RET_UNHANDLED) {               // unhandled due to a guard?
+
+            QS_BEGIN_(QS_QEP_UNHANDLED, QS::smObj_, this)
+                QS_SIG_(e->sig);                    // the signal of the event
+                QS_OBJ_(this);                    // this state machine object
+                QS_FUN_(s);                               // the current state
+            QS_END_()
+
+            r = QEP_TRIG_(s, QEP_EMPTY_SIG_);          // find superstate of s
+        }
+    } while (r == Q_RET_SUPER);
+
+    if (r == Q_RET_TRAN) {                                // transition taken?
+        QStateHandler path[QEP_MAX_NEST_DEPTH_];
+        int8_t ip = s8_n1;                      // transition entry path index
+        int8_t iq;                       // helper transition entry path index
+#ifdef Q_SPY
+        QStateHandler src = s;       // save the transition source for tracing
+#endif
+
+        path[0] = m_temp;                 // save the target of the transition
+        path[1] = t;
+
+        while (t != s) {       // exit current state to transition source s...
+            if (QEP_TRIG_(t, Q_EXIT_SIG) == Q_RET_HANDLED) {   //exit handled?
+                QS_BEGIN_(QS_QEP_STATE_EXIT, QS::smObj_, this)
+                    QS_OBJ_(this);                // this state machine object
+                    QS_FUN_(t);                            // the exited state
+                QS_END_()
+
+                (void)QEP_TRIG_(t, QEP_EMPTY_SIG_);    // find superstate of t
+            }
+            t = m_temp;                         // m_temp holds the superstate
+        }
+
+        t = path[0];                               // target of the transition
+
+        if (s == t) {         // (a) check source==target (transition to self)
+            QEP_EXIT_(s);                                   // exit the source
+            ip = s8_0;                                     // enter the target
+        }
+        else {
+            (void)QEP_TRIG_(t, QEP_EMPTY_SIG_);        // superstate of target
+            t = m_temp;
+            if (s == t) {                   // (b) check source==target->super
+                ip = s8_0;               // enter the target
+            }
+            else {
+                (void)QEP_TRIG_(s, QEP_EMPTY_SIG_);       // superstate of src
+                                     // (c) check source->super==target->super
+                if (m_temp == t) {
+                    QEP_EXIT_(s);                           // exit the source
+                    ip = s8_0;           // enter the target
+                }
+                else {
+                                            // (d) check source->super==target
+                    if (m_temp == path[0]) {
+                        QEP_EXIT_(s);                       // exit the source
+                    }
+                    else { // (e) check rest of source==target->super->super..
+                           // and store the entry path along the way
+                           //
+                        iq = s8_0; // indicate LCA not found
+                        ip = s8_1; // enter target's superst
+                        path[1] = t;          // save the superstate of target
+                        t = m_temp;                      // save source->super
+                                                  // find target->super->super
+                        r = QEP_TRIG_(path[1], QEP_EMPTY_SIG_);
+                        while (r == Q_RET_SUPER) {
+                            ++ip;
+                            path[ip] = m_temp;         // store the entry path
+                            if (m_temp == s) {            // is it the source?
+                                                    // indicate that LCA found
+                                iq = s8_1;
+                                               // entry path must not overflow
+                                Q_ASSERT(ip < QEP_MAX_NEST_DEPTH_);
+                                --ip;               // do not enter the source
+                                r = Q_RET_HANDLED;       // terminate the loop
+                            }
+                            else {      // it is not the source, keep going up
+                                r = QEP_TRIG_(m_temp, QEP_EMPTY_SIG_);
+                            }
+                        }
+                        if (iq == s8_0) {  // LCA found yet?
+
+                                               // entry path must not overflow
+                            Q_ASSERT(ip < QEP_MAX_NEST_DEPTH_);
+
+                            QEP_EXIT_(s);                   // exit the source
+
+                            // (f) check the rest of source->super
+                            //                  == target->super->super...
+                            //
+                            iq = ip;
+                            r = Q_RET_IGNORED;       // indicate LCA NOT found
+                            do {
+                                if (t == path[iq]) {       // is this the LCA?
+                                    r = Q_RET_HANDLED;   // indicate LCA found
+                                                           // do not enter LCA
+                                    ip = static_cast<int8_t>(iq - s8_1);
+                                                         // terminate the loop
+                                    iq = s8_n1;
+                                }
+                                else {
+                                    --iq;    // try lower superstate of target
+                                }
+                            } while (iq >= s8_0);
+
+                            if (r != Q_RET_HANDLED) {    // LCA not found yet?
+                                // (g) check each source->super->...
+                                // for each target->super...
+                                //
+                                r = Q_RET_IGNORED;             // keep looping
+                                do {
+                                                          // exit t unhandled?
+                                    if (QEP_TRIG_(t, Q_EXIT_SIG)
+                                        == Q_RET_HANDLED)
+                                    {
+                                        QS_BEGIN_(QS_QEP_STATE_EXIT,
+                                                  QS::smObj_, this)
+                                            QS_OBJ_(this);
+                                            QS_FUN_(t);
+                                        QS_END_()
+
+                                        (void)QEP_TRIG_(t, QEP_EMPTY_SIG_);
+                                    }
+                                    t = m_temp;          //  set to super of t
+                                    iq = ip;
+                                    do {
+                                        if (t == path[iq]) {   // is this LCA?
+                                                           // do not enter LCA
+                                            ip = static_cast<int8_t>(iq-s8_1);
+                                                // break out of the inner loop
+                                            iq = s8_n1;
+                                            r = Q_RET_HANDLED;  // break outer
+                                        }
+                                        else {
+                                            --iq;
+                                        }
+                                    } while (iq >= s8_0);
+                                } while (r != Q_RET_HANDLED);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+                       // retrace the entry path in reverse (desired) order...
+        for (; ip >= s8_0; --ip) {
+            QEP_ENTER_(path[ip]);                            // enter path[ip]
+        }
+        t = path[0];                         // stick the target into register
+        m_temp = t;                                   // update the next state
+
+                                         // drill into the target hierarchy...
+        while (QEP_TRIG_(t, Q_INIT_SIG) == Q_RET_TRAN) {
+
+            QS_BEGIN_(QS_QEP_STATE_INIT, QS::smObj_, this)
+                QS_OBJ_(this);                    // this state machine object
+                QS_FUN_(t);                        // the source (pseudo)state
+                QS_FUN_(m_temp);              // the target of the transition
+            QS_END_()
+
+            ip = s8_0;
+            path[0] = m_temp;
+            (void)QEP_TRIG_(m_temp, QEP_EMPTY_SIG_);       // find superstate
+            while (m_temp != t) {
+                ++ip;
+                path[ip] = m_temp;
+                (void)QEP_TRIG_(m_temp, QEP_EMPTY_SIG_);   // find superstate
+            }
+            m_temp = path[0];
+                                               // entry path must not overflow
+            Q_ASSERT(ip < QEP_MAX_NEST_DEPTH_);
+
+            do {       // retrace the entry path in reverse (correct) order...
+                QEP_ENTER_(path[ip]);                        // enter path[ip]
+                --ip;
+            } while (ip >= s8_0);
+
+            t = path[0];
+        }
+
+        QS_BEGIN_(QS_QEP_TRAN, QS::smObj_, this)
+            QS_TIME_();                                          // time stamp
+            QS_SIG_(e->sig);                        // the signal of the event
+            QS_OBJ_(this);                        // this state machine object
+            QS_FUN_(src);                      // the source of the transition
+            QS_FUN_(t);                                // the new active state
+        QS_END_()
+
+    }
+    else {                                             // transition not taken
+#ifdef Q_SPY
+        if (r == Q_RET_HANDLED) {
+
+            QS_BEGIN_(QS_QEP_INTERN_TRAN, QS::smObj_, this)
+                QS_TIME_();                                      // time stamp
+                QS_SIG_(e->sig);                    // the signal of the event
+                QS_OBJ_(this);                    // this state machine object
+                QS_FUN_(m_state);          // the state that handled the event
+            QS_END_()
+
+        }
+        else {
+
+            QS_BEGIN_(QS_QEP_IGNORED, QS::smObj_, this)
+                QS_TIME_();                                      // time stamp
+                QS_SIG_(e->sig);                    // the signal of the event
+                QS_OBJ_(this);                    // this state machine object
+                QS_FUN_(m_state);                         // the current state
+            QS_END_()
+
+        }
+#endif
+    }
+
+    m_state = t;                            // change the current active state
+    m_temp  = t;                           // mark the configuration as stable
+}
+
+QP_END_
+
+// "qf_pkg.h" ================================================================
+/// \brief Internal (package scope) QF/C++ interface.
+
+/// \brief helper macro to cast const away from an event pointer \a e_
+#define QF_EVT_CONST_CAST_(e_) const_cast<QEvt *>(e_)
+
+QP_BEGIN_
+                                               // QF-specific critical section
+#ifndef QF_CRIT_STAT_TYPE
+    /// \brief This is an internal macro for defining the critical section
+    /// status type.
+    ///
+    /// The purpose of this macro is to enable writing the same code for the
+    /// case when critical sectgion status type is defined and when it is not.
+    /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
+    /// provides the definition of the critical section status varaible.
+    /// Otherwise this macro is empty.
+    /// \sa #QF_CRIT_STAT_TYPE
+    ///
+    #define QF_CRIT_STAT_
+
+    /// \brief This is an internal macro for entering a critical section.
+    ///
+    /// The purpose of this macro is to enable writing the same code for the
+    /// case when critical sectgion status type is defined and when it is not.
+    /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
+    /// invokes #QF_CRIT_ENTRY passing the key variable as the parameter.
+    /// Otherwise #QF_CRIT_ENTRY is invoked with a dummy parameter.
+    /// \sa #QF_CRIT_ENTRY
+    ///
+    #define QF_CRIT_ENTRY_()    QF_CRIT_ENTRY(dummy)
+
+    /// \brief This is an internal macro for exiting a cricial section.
+    ///
+    /// The purpose of this macro is to enable writing the same code for the
+    /// case when critical sectgion status type is defined and when it is not.
+    /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
+    /// invokes #QF_CRIT_EXIT passing the key variable as the parameter.
+    /// Otherwise #QF_CRIT_EXIT is invoked with a dummy parameter.
+    /// \sa #QF_CRIT_EXIT
+    ///
+    #define QF_CRIT_EXIT_()     QF_CRIT_EXIT(dummy)
+
+#else
+    #define QF_CRIT_STAT_       QF_CRIT_STAT_TYPE critStat_;
+    #define QF_CRIT_ENTRY_()    QF_CRIT_ENTRY(critStat_)
+    #define QF_CRIT_EXIT_()     QF_CRIT_EXIT(critStat_)
+#endif
+
+// package-scope objects -----------------------------------------------------
+extern QTimeEvt *QF_timeEvtListHead_;  ///< head of linked list of time events
+extern QF_EPOOL_TYPE_ QF_pool_[QF_MAX_EPOOL];        ///< allocate event pools
+extern uint8_t QF_maxPool_;                  ///< # of initialized event pools
+extern QSubscrList *QF_subscrList_;             ///< the subscriber list array
+extern enum_t QF_maxSignal_;                 ///< the maximum published signal
+
+//............................................................................
+/// \brief Structure representing a free block in the Native QF Memory Pool
+/// \sa ::QMPool
+struct QFreeBlock {
+    QFreeBlock *m_next;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// internal helper inline functions
+
+/// \brief access to the poolId_ of an event \a e
+inline uint8_t QF_EVT_POOL_ID_(QEvt const * const e) { return e->poolId_; }
+
+/// \brief access to the refCtr_ of an event \a e
+inline uint8_t QF_EVT_REF_CTR_(QEvt const * const e) { return e->refCtr_; }
+
+/// \brief increment the refCtr_ of an event \a e
+inline void QF_EVT_REF_CTR_INC_(QEvt const * const e) {
+    ++(QF_EVT_CONST_CAST_(e))->refCtr_;
+}
+
+/// \brief decrement the refCtr_ of an event \a e
+inline void QF_EVT_REF_CTR_DEC_(QEvt const * const e) {
+    --(QF_EVT_CONST_CAST_(e))->refCtr_;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// internal frequently used srongly-typed constants
+
+QTimeEvtCtr const tc_0 = static_cast<QTimeEvtCtr>(0);
+
+void     * const null_void = static_cast<void *>(0);
+QEvt const * const null_evt  = static_cast<QEvt const *>(0);
+QTimeEvt * const null_tevt = static_cast<QTimeEvt *>(0);
+QActive  * const null_act  = static_cast<QActive *>(0);
+
+QP_END_
+
+/// \brief access element at index \a i_ from the base pointer \a base_
+#define QF_PTR_AT_(base_, i_) (base_[i_])
+
+//////////////////////////////////////////////////////////////////////////////
+#ifdef Q_SPY                                   // QS software tracing enabled?
+
+    #if (QF_EQUEUE_CTR_SIZE == 1)
+
+        /// \brief Internal QS macro to output an unformatted event queue
+        /// counter data element
+        /// \note the counter size depends on the macro #QF_EQUEUE_CTR_SIZE.
+        #define QS_EQC_(ctr_)       QS::u8_(ctr_)
+    #elif (QF_EQUEUE_CTR_SIZE == 2)
+        #define QS_EQC_(ctr_)       QS::u16_(ctr_)
+    #elif (QF_EQUEUE_CTR_SIZE == 4)
+        #define QS_EQC_(ctr_)       QS::u32_(ctr_)
+    #else
+        #error "QF_EQUEUE_CTR_SIZE not defined"
+    #endif
+
+
+    #if (QF_EVENT_SIZ_SIZE == 1)
+
+        /// \brief Internal QS macro to output an unformatted event size
+        /// data element
+        /// \note the event size depends on the macro #QF_EVENT_SIZ_SIZE.
+        #define QS_EVS_(size_)      QS::u8_(size_)
+    #elif (QF_EVENT_SIZ_SIZE == 2)
+        #define QS_EVS_(size_)      QS::u16_(size_)
+    #elif (QF_EVENT_SIZ_SIZE == 4)
+        #define QS_EVS_(size_)      QS::u32_(size_)
+    #endif
+
+
+    #if (QF_MPOOL_SIZ_SIZE == 1)
+
+        /// \brief Internal QS macro to output an unformatted memory pool
+        /// block-size data element
+        /// \note the block-size depends on the macro #QF_MPOOL_SIZ_SIZE.
+        #define QS_MPS_(size_)      QS::u8_(size_)
+    #elif (QF_MPOOL_SIZ_SIZE == 2)
+        #define QS_MPS_(size_)      QS::u16_(size_)
+    #elif (QF_MPOOL_SIZ_SIZE == 4)
+        #define QS_MPS_(size_)      QS::u32_(size_)
+    #endif
+
+    #if (QF_MPOOL_CTR_SIZE == 1)
+
+        /// \brief Internal QS macro to output an unformatted memory pool
+        /// block-counter data element
+        /// \note the counter size depends on the macro #QF_MPOOL_CTR_SIZE.
+        #define QS_MPC_(ctr_)       QS::u8_(ctr_)
+    #elif (QF_MPOOL_CTR_SIZE == 2)
+        #define QS_MPC_(ctr_)       QS::u16_(ctr_)
+    #elif (QF_MPOOL_CTR_SIZE == 4)
+        #define QS_MPC_(ctr_)       QS::u32_(ctr_)
+    #endif
+
+
+    #if (QF_TIMEEVT_CTR_SIZE == 1)
+
+        /// \brief Internal QS macro to output an unformatted time event
+        /// tick-counter data element
+        /// \note the counter size depends on the macro #QF_TIMEEVT_CTR_SIZE.
+        #define QS_TEC_(ctr_)       QS::u8_(ctr_)
+    #elif (QF_TIMEEVT_CTR_SIZE == 2)
+        #define QS_TEC_(ctr_)       QS::u16_(ctr_)
+    #elif (QF_TIMEEVT_CTR_SIZE == 4)
+        #define QS_TEC_(ctr_)       QS::u32_(ctr_)
+    #endif
+
+#endif                                                                // Q_SPY
+
+// "qa_defer.cpp" ============================================================
+/// \brief QActive::defer() and QActive::recall() implementation.
+///
+
+QP_BEGIN_
+
+//............................................................................
+void QActive::defer(QEQueue * const eq, QEvt const * const e) const {
+    eq->postFIFO(e);
+}
+//............................................................................
+bool QActive::recall(QEQueue * const eq) {
+    QEvt const * const e = eq->get();  // try to get evt from deferred queue
+    bool const recalled = (e != null_evt);                 // event available?
+    if (recalled) {
+        postLIFO(e);      // post it to the front of the Active Object's queue
+
+        QF_CRIT_STAT_
+        QF_CRIT_ENTRY_();
+
+        if (QF_EVT_POOL_ID_(e) != u8_0) {            // is it a dynamic event?
+
+            // after posting to the AO's queue the event must be referenced
+            // at least twice: once in the deferred event queue (eq->get()
+            // did NOT decrement the reference counter) and once in the
+            // AO's event queue.
+            Q_ASSERT(QF_EVT_REF_CTR_(e) > u8_1);
+
+            // we need to decrement the reference counter once, to account
+            // for removing the event from the deferred event queue.
+            //
+            QF_EVT_REF_CTR_DEC_(e);         // decrement the reference counter
+        }
+
+        QF_CRIT_EXIT_();
+    }
+    return recalled;                                     // event not recalled
+}
+
+QP_END_
+
+
+// "qa_fifo.cpp" =============================================================
+/// \brief QActive::postFIFO() implementation.
+///
+/// \note this source file is only included in the QF library when the native
+/// QF active object queue is used (instead of a message queue of an RTOS).
+
+QP_BEGIN_
+
+//............................................................................
+#ifndef Q_SPY
+void QActive::postFIFO(QEvt const * const e) {
+#else
+void QActive::postFIFO(QEvt const * const e, void const * const sender) {
+#endif
+
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+
+    QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_FIFO, QS::aoObj_, this)
+        QS_TIME_();                                               // timestamp
+        QS_OBJ_(sender);                                  // the sender object
+        QS_SIG_(e->sig);                            // the signal of the event
+        QS_OBJ_(this);                                   // this active object
+        QS_U8_(QF_EVT_POOL_ID_(e));                // the pool Id of the event
+        QS_U8_(QF_EVT_REF_CTR_(e));              // the ref count of the event
+        QS_EQC_(m_eQueue.m_nFree);                   // number of free entries
+        QS_EQC_(m_eQueue.m_nMin);                // min number of free entries
+    QS_END_NOCRIT_()
+
+    if (QF_EVT_POOL_ID_(e) != u8_0) {                // is it a dynamic event?
+        QF_EVT_REF_CTR_INC_(e);             // increment the reference counter
+    }
+
+    if (m_eQueue.m_frontEvt == null_evt) {              // is the queue empty?
+        m_eQueue.m_frontEvt = e;                     // deliver event directly
+        QACTIVE_EQUEUE_SIGNAL_(this);                // signal the event queue
+    }
+    else {               // queue is not empty, leave event in the ring-buffer
+                                        // queue must accept all posted events
+        Q_ASSERT(m_eQueue.m_nFree != static_cast<QEQueueCtr>(0));
+                              // insert event pointer e into the buffer (FIFO)
+        QF_PTR_AT_(m_eQueue.m_ring, m_eQueue.m_head) = e;
+        if (m_eQueue.m_head == static_cast<QEQueueCtr>(0)) {  // need to wrap?
+            m_eQueue.m_head = m_eQueue.m_end;                   // wrap around
+        }
+        --m_eQueue.m_head;
+
+        --m_eQueue.m_nFree;                    // update number of free events
+        if (m_eQueue.m_nMin > m_eQueue.m_nFree) {
+            m_eQueue.m_nMin = m_eQueue.m_nFree;       // update minimum so far
+        }
+    }
+    QF_CRIT_EXIT_();
+}
+
+QP_END_
+
+// "qa_get_.cpp" =============================================================
+/// \brief QActive::get_() and QF::getQueueMargin() definitions.
+///
+/// \note this source file is only included in the QF library when the native
+/// QF active object queue is used (instead of a message queue of an RTOS).
+
+QP_BEGIN_
+
+//............................................................................
+QEvt const *QActive::get_(void) {
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+
+    QACTIVE_EQUEUE_WAIT_(this);           // wait for event to arrive directly
+
+    QEvt const *e = m_eQueue.m_frontEvt;
+
+    if (m_eQueue.m_nFree != m_eQueue.m_end) { //any events in the ring buffer?
+                                                 // remove event from the tail
+        m_eQueue.m_frontEvt = QF_PTR_AT_(m_eQueue.m_ring, m_eQueue.m_tail);
+        if (m_eQueue.m_tail == static_cast<QEQueueCtr>(0)) {  // need to wrap?
+            m_eQueue.m_tail = m_eQueue.m_end;                   // wrap around
+        }
+        --m_eQueue.m_tail;
+
+        ++m_eQueue.m_nFree;          // one more free event in the ring buffer
+
+        QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_GET, QS::aoObj_, this)
+            QS_TIME_();                                           // timestamp
+            QS_SIG_(e->sig);                       // the signal of this event
+            QS_OBJ_(this);                               // this active object
+            QS_U8_(QF_EVT_POOL_ID_(e));            // the pool Id of the event
+            QS_U8_(QF_EVT_REF_CTR_(e));          // the ref count of the event
+            QS_EQC_(m_eQueue.m_nFree);               // number of free entries
+        QS_END_NOCRIT_()
+    }
+    else {
+        m_eQueue.m_frontEvt = null_evt;             // the queue becomes empty
+        QACTIVE_EQUEUE_ONEMPTY_(this);
+
+        QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_GET_LAST, QS::aoObj_, this)
+            QS_TIME_();                                           // timestamp
+            QS_SIG_(e->sig);                       // the signal of this event
+            QS_OBJ_(this);                               // this active object
+            QS_U8_(QF_EVT_POOL_ID_(e));            // the pool Id of the event
+            QS_U8_(QF_EVT_REF_CTR_(e));          // the ref count of the event
+        QS_END_NOCRIT_()
+    }
+    QF_CRIT_EXIT_();
+    return e;
+}
+//............................................................................
+uint32_t QF::getQueueMargin(uint8_t const prio) {
+    Q_REQUIRE((prio <= static_cast<uint8_t>(QF_MAX_ACTIVE))
+              && (active_[prio] != static_cast<QActive *>(0)));
+
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+    uint32_t margin = static_cast<uint32_t>(active_[prio]->m_eQueue.m_nMin);
+    QF_CRIT_EXIT_();
+
+    return margin;
+}
+
+QP_END_
+
+// "qa_lifo.cpp" =============================================================
+/// \brief QActive::postLIFO() implementation.
+///
+/// \note this source file is only included in the QF library when the native
+/// QF active object queue is used (instead of a message queue of an RTOS).
+
+QP_BEGIN_
+
+//............................................................................
+void QActive::postLIFO(QEvt const * const e) {
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+
+    QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_LIFO, QS::aoObj_, this)
+        QS_TIME_();                                               // timestamp
+        QS_SIG_(e->sig);                           // the signal of this event
+        QS_OBJ_(this);                                   // this active object
+        QS_U8_(QF_EVT_POOL_ID_(e));                // the pool Id of the event
+        QS_U8_(QF_EVT_REF_CTR_(e));              // the ref count of the event
+        QS_EQC_(m_eQueue.m_nFree);                   // number of free entries
+        QS_EQC_(m_eQueue.m_nMin);                // min number of free entries
+    QS_END_NOCRIT_()
+
+    if (QF_EVT_POOL_ID_(e) != u8_0) {                // is it a dynamic event?
+        QF_EVT_REF_CTR_INC_(e);             // increment the reference counter
+    }
+
+    if (m_eQueue.m_frontEvt == null_evt) {              // is the queue empty?
+        m_eQueue.m_frontEvt = e;                     // deliver event directly
+        QACTIVE_EQUEUE_SIGNAL_(this);                // signal the event queue
+    }
+    else {               // queue is not empty, leave event in the ring-buffer
+                                        // queue must accept all posted events
+        Q_ASSERT(m_eQueue.m_nFree != static_cast<QEQueueCtr>(0));
+
+        ++m_eQueue.m_tail;
+        if (m_eQueue.m_tail == m_eQueue.m_end) {     // need to wrap the tail?
+            m_eQueue.m_tail = static_cast<QEQueueCtr>(0);       // wrap around
+        }
+
+        QF_PTR_AT_(m_eQueue.m_ring, m_eQueue.m_tail) = m_eQueue.m_frontEvt;
+        m_eQueue.m_frontEvt = e;                         // put event to front
+
+        --m_eQueue.m_nFree;                    // update number of free events
+        if (m_eQueue.m_nMin > m_eQueue.m_nFree) {
+            m_eQueue.m_nMin = m_eQueue.m_nFree;       // update minimum so far
+        }
+    }
+    QF_CRIT_EXIT_();
+}
+
+QP_END_
+
+// "qa_sub.cpp" ==============================================================
+/// \brief QActive::subscribe() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+void QActive::subscribe(enum_t const sig) const {
+    uint8_t p = m_prio;
+    Q_REQUIRE((Q_USER_SIG <= sig)
+              && (sig < QF_maxSignal_)
+              && (u8_0 < p) && (p <= static_cast<uint8_t>(QF_MAX_ACTIVE))
+              && (QF::active_[p] == this));
+
+    uint8_t const i = Q_ROM_BYTE(QF_div8Lkup[p]);
+
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+
+    QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_SUBSCRIBE, QS::aoObj_, this)
+        QS_TIME_();                                               // timestamp
+        QS_SIG_(sig);                              // the signal of this event
+        QS_OBJ_(this);                                   // this active object
+    QS_END_NOCRIT_()
+                                                       // set the priority bit
+    QF_PTR_AT_(QF_subscrList_, sig).m_bits[i] |= Q_ROM_BYTE(QF_pwr2Lkup[p]);
+    QF_CRIT_EXIT_();
+}
+
+QP_END_
+
+// "qa_usub.cpp" =============================================================
+/// \brief QActive::unsubscribe() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+void QActive::unsubscribe(enum_t const sig) const {
+    uint8_t p = m_prio;
+    Q_REQUIRE((Q_USER_SIG <= sig)
+              && (sig < QF_maxSignal_)
+              && (u8_0 < p) && (p <= static_cast<uint8_t>(QF_MAX_ACTIVE))
+              && (QF::active_[p] == this));
+
+    uint8_t const i = Q_ROM_BYTE(QF_div8Lkup[p]);
+
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+
+    QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_UNSUBSCRIBE, QS::aoObj_, this)
+        QS_TIME_();                                               // timestamp
+        QS_SIG_(sig);                              // the signal of this event
+        QS_OBJ_(this);                                   // this active object
+    QS_END_NOCRIT_()
+                                                     // clear the priority bit
+    QF_PTR_AT_(QF_subscrList_,sig).m_bits[i] &= Q_ROM_BYTE(QF_invPwr2Lkup[p]);
+    QF_CRIT_EXIT_();
+}
+
+QP_END_
+
+// "qa_usuba.cpp" ============================================================
+/// \brief QActive::unsubscribeAll() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+void QActive::unsubscribeAll(void) const {
+    uint8_t const p = m_prio;
+    Q_REQUIRE((u8_0 < p) && (p <= static_cast<uint8_t>(QF_MAX_ACTIVE))
+              && (QF::active_[p] == this));
+
+    uint8_t const i = Q_ROM_BYTE(QF_div8Lkup[p]);
+
+    enum_t sig;
+    for (sig = Q_USER_SIG; sig < QF_maxSignal_; ++sig) {
+        QF_CRIT_STAT_
+        QF_CRIT_ENTRY_();
+        if ((QF_PTR_AT_(QF_subscrList_, sig).m_bits[i]
+             & Q_ROM_BYTE(QF_pwr2Lkup[p])) != u8_0)
+        {
+
+            QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_UNSUBSCRIBE, QS::aoObj_, this)
+                QS_TIME_();                                       // timestamp
+                QS_SIG_(sig);                      // the signal of this event
+                QS_OBJ_(this);                           // this active object
+            QS_END_NOCRIT_()
+                                                     // clear the priority bit
+            QF_PTR_AT_(QF_subscrList_, sig).m_bits[i] &=
+                Q_ROM_BYTE(QF_invPwr2Lkup[p]);
+        }
+        QF_CRIT_EXIT_();
+    }
+}
+
+QP_END_
+
+// "qeq_fifo.cpp" ============================================================
+/// \brief QEQueue::postFIFO() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+void QEQueue::postFIFO(QEvt const * const e) {
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+
+    QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_POST_FIFO, QS::eqObj_, this)
+        QS_TIME_();                                               // timestamp
+        QS_SIG_(e->sig);                           // the signal of this event
+        QS_OBJ_(this);                                    // this queue object
+        QS_U8_(QF_EVT_POOL_ID_(e));                // the pool Id of the event
+        QS_U8_(QF_EVT_REF_CTR_(e));              // the ref count of the event
+        QS_EQC_(m_nFree);                            // number of free entries
+        QS_EQC_(m_nMin);                         // min number of free entries
+    QS_END_NOCRIT_()
+
+    if (QF_EVT_POOL_ID_(e) != u8_0) {                // is it a dynamic event?
+        QF_EVT_REF_CTR_INC_(e);             // increment the reference counter
+    }
+
+    if (m_frontEvt == null_evt) {                       // is the queue empty?
+        m_frontEvt = e;                              // deliver event directly
+    }
+    else {               // queue is not empty, leave event in the ring-buffer
+               // the queue must be able to accept the event (cannot overflow)
+        Q_ASSERT(m_nFree != static_cast<QEQueueCtr>(0));
+
+        QF_PTR_AT_(m_ring, m_head) = e; // insert event into the buffer (FIFO)
+        if (m_head == static_cast<QEQueueCtr>(0)) {           // need to wrap?
+            m_head = m_end;                                     // wrap around
+        }
+        --m_head;
+
+        --m_nFree;                             // update number of free events
+        if (m_nMin > m_nFree) {
+            m_nMin = m_nFree;                         // update minimum so far
+        }
+    }
+    QF_CRIT_EXIT_();
+}
+
+QP_END_
+
+// "qeq_get.cpp" =============================================================
+/// \brief QEQueue::get() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+QEvt const *QEQueue::get(void) {
+    QEvt const *e;
+    QF_CRIT_STAT_
+
+    QF_CRIT_ENTRY_();
+    if (m_frontEvt == null_evt) {                       // is the queue empty?
+        e = null_evt;                       // no event available at this time
+    }
+    else {
+        e = m_frontEvt;
+
+        if (m_nFree != m_end) {          // any events in the the ring buffer?
+            m_frontEvt = QF_PTR_AT_(m_ring, m_tail);   // remove from the tail
+            if (m_tail == static_cast<QEQueueCtr>(0)) {       // need to wrap?
+                m_tail = m_end;                                 // wrap around
+            }
+            --m_tail;
+
+            ++m_nFree;               // one more free event in the ring buffer
+
+            QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_GET, QS::eqObj_, this)
+                QS_TIME_();                                       // timestamp
+                QS_SIG_(e->sig);                   // the signal of this event
+                QS_OBJ_(this);                            // this queue object
+                QS_U8_(QF_EVT_POOL_ID_(e));        // the pool Id of the event
+                QS_U8_(QF_EVT_REF_CTR_(e));      // the ref count of the event
+                QS_EQC_(m_nFree);                    // number of free entries
+            QS_END_NOCRIT_()
+        }
+        else {
+            m_frontEvt = null_evt;                  // the queue becomes empty
+
+            QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_GET_LAST, QS::eqObj_, this)
+                QS_TIME_();                                       // timestamp
+                QS_SIG_(e->sig);                   // the signal of this event
+                QS_OBJ_(this);                            // this queue object
+                QS_U8_(QF_EVT_POOL_ID_(e));        // the pool Id of the event
+                QS_U8_(QF_EVT_REF_CTR_(e));      // the ref count of the event
+            QS_END_NOCRIT_()
+        }
+    }
+    QF_CRIT_EXIT_();
+    return e;
+}
+
+QP_END_
+
+// "qeq_init.cpp" ============================================================
+/// \brief QEQueue::init() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+void QEQueue::init(QEvt const *qSto[], QEQueueCtr const qLen) {
+    m_frontEvt = null_evt;                           // no events in the queue
+    m_ring     = &qSto[0];
+    m_end      = qLen;
+    m_head     = static_cast<QEQueueCtr>(0);
+    m_tail     = static_cast<QEQueueCtr>(0);
+    m_nFree    = qLen;
+    m_nMin     = qLen;
+
+    QS_CRIT_STAT_
+    QS_BEGIN_(QS_QF_EQUEUE_INIT, QS::eqObj_, this)
+        QS_OBJ_(qSto);                                  // this QEQueue object
+        QS_EQC_(qLen);                              // the length of the queue
+    QS_END_()
+}
+
+QP_END_
+
+// "qeq_lifo.cpp" ============================================================
+/// \brief QEQueue::postLIFO() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+void QEQueue::postLIFO(QEvt const * const e) {
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+
+    QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_POST_LIFO, QS::eqObj_, this)
+        QS_TIME_();                                               // timestamp
+        QS_SIG_(e->sig);                           // the signal of this event
+        QS_OBJ_(this);                                    // this queue object
+        QS_U8_(QF_EVT_POOL_ID_(e));                // the pool Id of the event
+        QS_U8_(QF_EVT_REF_CTR_(e));              // the ref count of the event
+        QS_EQC_(m_nFree);                            // number of free entries
+        QS_EQC_(m_nMin);                         // min number of free entries
+    QS_END_NOCRIT_()
+
+    if (QF_EVT_POOL_ID_(e) != u8_0) {                // is it a dynamic event?
+        QF_EVT_REF_CTR_INC_(e);             // increment the reference counter
+    }
+
+    if (m_frontEvt != null_evt) {                   // is the queue not empty?
+               // the queue must be able to accept the event (cannot overflow)
+        Q_ASSERT(m_nFree != static_cast<QEQueueCtr>(0));
+
+        ++m_tail;
+        if (m_tail == m_end) {                       // need to wrap the tail?
+            m_tail = static_cast<QEQueueCtr>(0);                // wrap around
+        }
+
+        QF_PTR_AT_(m_ring, m_tail) = m_frontEvt;   // buffer the old front evt
+
+        --m_nFree;                             // update number of free events
+        if (m_nMin > m_nFree) {
+            m_nMin = m_nFree;                         // update minimum so far
+        }
+    }
+
+    m_frontEvt = e;                        // stick the new event to the front
+
+    QF_CRIT_EXIT_();
+}
+
+QP_END_
+
+// "qf_act.cpp" ==============================================================
+/// \brief QF::active_[], QF::getVersion(), and QF::add_()/QF::remove_()
+/// implementation.
+
+QP_BEGIN_
+
+// public objects ------------------------------------------------------------
+QActive *QF::active_[QF_MAX_ACTIVE + 1];        // to be used by QF ports only
+uint8_t QF_intLockNest_;                       // interrupt-lock nesting level
+
+//............................................................................
+char_t const Q_ROM * Q_ROM_VAR QF::getVersion(void) {
+    uint8_t const u8_zero = static_cast<uint8_t>('0');
+    static char_t const Q_ROM Q_ROM_VAR version[] = {
+        static_cast<char_t>(((QP_VERSION >> 12) & 0xFU) + u8_zero),
+        static_cast<char_t>('.'),
+        static_cast<char_t>(((QP_VERSION >>  8) & 0xFU) + u8_zero),
+        static_cast<char_t>('.'),
+        static_cast<char_t>(((QP_VERSION >>  4) & 0xFU) + u8_zero),
+        static_cast<char_t>((QP_VERSION         & 0xFU) + u8_zero),
+        static_cast<char_t>('\0')
+    };
+    return version;
+}
+//............................................................................
+void QF::add_(QActive * const a) {
+    uint8_t p = a->m_prio;
+
+    Q_REQUIRE((u8_0 < p) && (p <= static_cast<uint8_t>(QF_MAX_ACTIVE))
+              && (active_[p] == static_cast<QActive *>(0)));
+
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+
+    active_[p] = a;            // registger the active object at this priority
+
+    QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_ADD, QS::aoObj_, a)
+        QS_TIME_();                                               // timestamp
+        QS_OBJ_(a);                                       // the active object
+        QS_U8_(p);                        // the priority of the active object
+    QS_END_NOCRIT_()
+
+    QF_CRIT_EXIT_();
+}
+//............................................................................
+void QF::remove_(QActive const * const a) {
+    uint8_t p = a->m_prio;
+
+    Q_REQUIRE((u8_0 < p) && (p <= static_cast<uint8_t>(QF_MAX_ACTIVE))
+              && (active_[p] == a));
+
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+
+    active_[p] = static_cast<QActive *>(0);      // free-up the priority level
+
+    QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_REMOVE, QS::aoObj_, a)
+        QS_TIME_();                                               // timestamp
+        QS_OBJ_(a);                                       // the active object
+        QS_U8_(p);                        // the priority of the active object
+    QS_END_NOCRIT_()
+
+    QF_CRIT_EXIT_();
+}
+
+QP_END_
+
+
+// "qf_gc.cpp" ===============================================================
+/// \brief QF::gc() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+void QF::gc(QEvt const * const e) {
+    if (QF_EVT_POOL_ID_(e) != u8_0) {                // is it a dynamic event?
+        QF_CRIT_STAT_
+        QF_CRIT_ENTRY_();
+
+        if (QF_EVT_REF_CTR_(e) > u8_1) {     // isn't this the last reference?
+            QF_EVT_REF_CTR_DEC_(e);               // decrement the ref counter
+
+            QS_BEGIN_NOCRIT_(QS_QF_GC_ATTEMPT, null_void, null_void)
+                QS_TIME_();                                       // timestamp
+                QS_SIG_(e->sig);                    // the signal of the event
+                QS_U8_(QF_EVT_POOL_ID_(e));        // the pool Id of the event
+                QS_U8_(QF_EVT_REF_CTR_(e));      // the ref count of the event
+            QS_END_NOCRIT_()
+
+            QF_CRIT_EXIT_();
+        }
+        else {         // this is the last reference to this event, recycle it
+            uint8_t idx = static_cast<uint8_t>(QF_EVT_POOL_ID_(e) - u8_1);
+
+            QS_BEGIN_NOCRIT_(QS_QF_GC, null_void, null_void)
+                QS_TIME_();                                       // timestamp
+                QS_SIG_(e->sig);                    // the signal of the event
+                QS_U8_(QF_EVT_POOL_ID_(e));        // the pool Id of the event
+                QS_U8_(QF_EVT_REF_CTR_(e));      // the ref count of the event
+            QS_END_NOCRIT_()
+
+            QF_CRIT_EXIT_();
+
+            Q_ASSERT(idx < QF_maxPool_);
+
+#ifdef Q_EVT_VIRTUAL
+            QF_EVT_CONST_CAST_(e)->~QEvt();        // xtor, cast 'const' away,
+                             // which is legitimate, because it's a pool event
+#endif
+                  // cast 'const' away, which is OK, because it's a pool event
+            QF_EPOOL_PUT_(QF_pool_[idx], QF_EVT_CONST_CAST_(e));
+        }
+    }
+}
+
+QP_END_
+
+// "qf_log2.cpp" =============================================================
+/// \brief QF_log2Lkup[] implementation.
+
+QP_BEGIN_
+
+// Global objects ------------------------------------------------------------
+uint8_t const Q_ROM Q_ROM_VAR QF_log2Lkup[256] = {
+    static_cast<uint8_t>(0),
+    static_cast<uint8_t>(1),
+    static_cast<uint8_t>(2), static_cast<uint8_t>(2),
+    static_cast<uint8_t>(3), static_cast<uint8_t>(3), static_cast<uint8_t>(3),
+    static_cast<uint8_t>(3),
+    static_cast<uint8_t>(4), static_cast<uint8_t>(4), static_cast<uint8_t>(4),
+    static_cast<uint8_t>(4), static_cast<uint8_t>(4), static_cast<uint8_t>(4),
+    static_cast<uint8_t>(4), static_cast<uint8_t>(4),
+    static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
+    static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
+    static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
+    static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
+    static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
+    static_cast<uint8_t>(5),
+    static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
+    static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
+    static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
+    static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
+    static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
+    static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
+    static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
+    static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
+    static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
+    static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
+    static_cast<uint8_t>(6), static_cast<uint8_t>(6),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
+    static_cast<uint8_t>(8), static_cast<uint8_t>(8)
+};
+
+QP_END_
+
+// "qf_new.cpp" ==============================================================
+/// \brief QF::new_() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+QEvt *QF::new_(QEvtSize const evtSize, enum_t const sig) {
+                    // find the pool id that fits the requested event size ...
+    uint8_t idx = u8_0;
+    while (evtSize
+           > static_cast<QEvtSize>(QF_EPOOL_EVENT_SIZE_(QF_pool_[idx])))
+    {
+        ++idx;
+        Q_ASSERT(idx < QF_maxPool_);     // cannot run out of registered pools
+    }
+
+    QS_CRIT_STAT_
+    QS_BEGIN_(QS_QF_NEW, null_void, null_void)
+        QS_TIME_();                                               // timestamp
+        QS_EVS_(evtSize);                             // the size of the event
+        QS_SIG_(static_cast<QSignal>(sig));         // the signal of the event
+    QS_END_()
+
+    QEvt *e;
+    QF_EPOOL_GET_(QF_pool_[idx], e);
+    Q_ASSERT(e != static_cast<QEvt *>(0));// pool must not run out of events
+
+    e->sig     = static_cast<QSignal>(sig);       // set signal for this event
+    e->poolId_ = static_cast<uint8_t>(idx + u8_1); // store pool ID in the evt
+    e->refCtr_ = u8_0;                       // set the reference counter to 0
+
+    return e;
+}
+
+QP_END_
+
+// "qf_pool.cpp" =============================================================
+/// \brief QF_pool_[] and QF_maxPool_ definition, QF::poolInit()
+/// implementation.
+
+QP_BEGIN_
+
+// Package-scope objects -----------------------------------------------------
+QF_EPOOL_TYPE_ QF_pool_[QF_MAX_EPOOL];             // allocate the event pools
+uint8_t QF_maxPool_;                      // number of initialized event pools
+
+//............................................................................
+void QF::poolInit(void * const poolSto,
+                  uint32_t const poolSize, uint32_t const evtSize)
+{
+                         // cannot exceed the number of available memory pools
+    Q_REQUIRE(QF_maxPool_ < static_cast<uint8_t>(Q_DIM(QF_pool_)));
+               // please initialize event pools in ascending order of evtSize:
+    Q_REQUIRE((QF_maxPool_ == u8_0)
+              || (QF_EPOOL_EVENT_SIZE_(QF_pool_[QF_maxPool_ - u8_1])
+                  < evtSize));
+    QF_EPOOL_INIT_(QF_pool_[QF_maxPool_], poolSto, poolSize, evtSize);
+    ++QF_maxPool_;                                            // one more pool
+}
+
+QP_END_
+
+
+// "qf_psini.cpp" ============================================================
+/// \brief QF_subscrList_ and QF_maxSignal_ definition, QF::psInit()
+/// implementation.
+
+QP_BEGIN_
+
+// Package-scope objects -----------------------------------------------------
+QSubscrList *QF_subscrList_;
+enum_t QF_maxSignal_;
+
+//............................................................................
+void QF::psInit(QSubscrList * const subscrSto, uint32_t const maxSignal) {
+    QF_subscrList_ = subscrSto;
+    QF_maxSignal_  = static_cast<enum_t>(maxSignal);
+}
+
+QP_END_
+
+// "qf_pspub.cpp" ============================================================
+/// \brief QF::publish() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+#ifndef Q_SPY
+void QF::publish(QEvt const * const e) {
+#else
+void QF::publish(QEvt const * const e, void const * const sender) {
+#endif
+         // make sure that the published signal is within the configured range
+    Q_REQUIRE(static_cast<enum_t>(e->sig) < QF_maxSignal_);
+
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+
+    QS_BEGIN_NOCRIT_(QS_QF_PUBLISH, null_void, null_void)
+        QS_TIME_();                                           // the timestamp
+        QS_OBJ_(sender);                                  // the sender object
+        QS_SIG_(e->sig);                            // the signal of the event
+        QS_U8_(QF_EVT_POOL_ID_(e));                // the pool Id of the event
+        QS_U8_(QF_EVT_REF_CTR_(e));              // the ref count of the event
+    QS_END_NOCRIT_()
+
+    if (QF_EVT_POOL_ID_(e) != u8_0) {                // is it a dynamic event?
+        QF_EVT_REF_CTR_INC_(e);     // increment the reference counter, NOTE01
+    }
+    QF_CRIT_EXIT_();
+
+#if (QF_MAX_ACTIVE <= 8)
+    uint8_t tmp = QF_PTR_AT_(QF_subscrList_, e->sig).m_bits[0];
+    while (tmp != u8_0) {
+        uint8_t p = Q_ROM_BYTE(QF_log2Lkup[tmp]);
+        tmp &= Q_ROM_BYTE(QF_invPwr2Lkup[p]);      // clear the subscriber bit
+        Q_ASSERT(active_[p] != static_cast<QActive *>(0));//must be registered
+
+                           // POST() asserts internally if the queue overflows
+        active_[p]->POST(e, sender);
+    }
+#else
+                                                // number of bytes in the list
+    uint8_t i = QF_SUBSCR_LIST_SIZE;
+    do {                       // go through all bytes in the subsciption list
+        --i;
+        uint8_t tmp = QF_PTR_AT_(QF_subscrList_, e->sig).m_bits[i];
+        while (tmp != u8_0) {
+            uint8_t p = Q_ROM_BYTE(QF_log2Lkup[tmp]);
+            tmp &= Q_ROM_BYTE(QF_invPwr2Lkup[p]);  // clear the subscriber bit
+                                                        // adjust the priority
+            p = static_cast<uint8_t>(p + static_cast<uint8_t>(i << 3));
+            Q_ASSERT(active_[p] != static_cast<QActive *>(0));   // registered
+
+                           // POST() asserts internally if the queue overflows
+            active_[p]->POST(e, sender);
+        }
+    } while (i != u8_0);
+#endif
+
+    gc(e);                            // run the garbage collector, see NOTE01
+}
+
+QP_END_
+
+
+// "qf_pwr2.cpp" =============================================================
+/// \brief QF_pwr2Lkup[], QF_invPwr2Lkup[], and QF_div8Lkup[] definitions.
+
+QP_BEGIN_
+
+// Global objects ------------------------------------------------------------
+uint8_t const Q_ROM Q_ROM_VAR QF_pwr2Lkup[65] = {
+    static_cast<uint8_t>(0x00),                             // unused location
+    static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
+    static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
+    static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
+    static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
+    static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
+    static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
+    static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
+    static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
+    static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
+    static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
+    static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
+    static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
+    static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
+    static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
+    static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
+    static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
+    static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
+    static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
+    static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
+    static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
+    static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
+    static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
+    static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
+    static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
+    static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
+    static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
+    static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
+    static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
+    static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
+    static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
+    static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
+    static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80)
+};
+
+uint8_t const Q_ROM Q_ROM_VAR QF_invPwr2Lkup[65] = {
+    static_cast<uint8_t>(0xFF),                             // unused location
+    static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
+    static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
+    static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
+    static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
+    static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
+    static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
+    static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
+    static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
+    static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
+    static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
+    static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
+    static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
+    static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
+    static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
+    static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
+    static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
+    static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
+    static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
+    static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
+    static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
+    static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
+    static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
+    static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
+    static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
+    static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
+    static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
+    static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
+    static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
+    static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
+    static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
+    static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
+    static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F)
+};
+
+uint8_t const Q_ROM Q_ROM_VAR QF_div8Lkup[65] = {
+    static_cast<uint8_t>(0),                                // unused location
+    static_cast<uint8_t>(0), static_cast<uint8_t>(0), static_cast<uint8_t>(0),
+    static_cast<uint8_t>(0), static_cast<uint8_t>(0), static_cast<uint8_t>(0),
+    static_cast<uint8_t>(0), static_cast<uint8_t>(0),
+    static_cast<uint8_t>(1), static_cast<uint8_t>(1), static_cast<uint8_t>(1),
+    static_cast<uint8_t>(1), static_cast<uint8_t>(1), static_cast<uint8_t>(1),
+    static_cast<uint8_t>(1), static_cast<uint8_t>(1),
+    static_cast<uint8_t>(2), static_cast<uint8_t>(2), static_cast<uint8_t>(2),
+    static_cast<uint8_t>(2), static_cast<uint8_t>(2), static_cast<uint8_t>(2),
+    static_cast<uint8_t>(2), static_cast<uint8_t>(2),
+    static_cast<uint8_t>(3), static_cast<uint8_t>(3), static_cast<uint8_t>(3),
+    static_cast<uint8_t>(3), static_cast<uint8_t>(3), static_cast<uint8_t>(3),
+    static_cast<uint8_t>(3), static_cast<uint8_t>(3),
+    static_cast<uint8_t>(4), static_cast<uint8_t>(4), static_cast<uint8_t>(4),
+    static_cast<uint8_t>(4), static_cast<uint8_t>(4), static_cast<uint8_t>(4),
+    static_cast<uint8_t>(4), static_cast<uint8_t>(4),
+    static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
+    static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
+    static_cast<uint8_t>(5), static_cast<uint8_t>(5),
+    static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
+    static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
+    static_cast<uint8_t>(6), static_cast<uint8_t>(6),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
+    static_cast<uint8_t>(7), static_cast<uint8_t>(7)
+};
+
+QP_END_
+
+// "qf_tick.cpp" =============================================================
+/// \brief QF::tick() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+#ifndef Q_SPY
+void QF::tick(void) {                                            // see NOTE01
+#else
+void QF::tick(void const * const sender) {
+#endif
+
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+
+    QS_BEGIN_NOCRIT_(QS_QF_TICK, null_void, null_void)
+        QS_TEC_(static_cast<QTimeEvtCtr>(++QS::tickCtr_)); // the tick counter
+    QS_END_NOCRIT_()
+
+    QTimeEvt *prev = null_tevt;
+    for (QTimeEvt *t = QF_timeEvtListHead_; t != null_tevt; t = t->m_next) {
+        if (t->m_ctr == tc_0) {            // time evt. scheduled for removal?
+            if (t == QF_timeEvtListHead_) {
+                QF_timeEvtListHead_ = t->m_next;
+            }
+            else {
+                Q_ASSERT(prev != null_tevt);
+                prev->m_next = t->m_next;
+            }
+            QF_EVT_REF_CTR_DEC_(t);                      // mark as not linked
+        }
+        else {
+            --t->m_ctr;
+            if (t->m_ctr == tc_0) {                        // about to expire?
+                if (t->m_interval != tc_0) {           // periodic time event?
+                    t->m_ctr = t->m_interval;            // rearm the time evt
+                }
+                else {
+                    QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_AUTO_DISARM, QS::teObj_, t)
+                        QS_OBJ_(t);                  // this time event object
+                        QS_OBJ_(t->m_act);                // the active object
+                    QS_END_NOCRIT_()
+                }
+
+                QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_POST, QS::teObj_, t)
+                    QS_TIME_();                                   // timestamp
+                    QS_OBJ_(t);                       // the time event object
+                    QS_SIG_(t->sig);          // the signal of this time event
+                    QS_OBJ_(t->m_act);                    // the active object
+                QS_END_NOCRIT_()
+
+                QF_CRIT_EXIT_();         // leave crit. section before posting
+                           // POST() asserts internally if the queue overflows
+                t->m_act->POST(t, sender);
+                QF_CRIT_ENTRY_();        // re-enter crit. section to continue
+
+                if (t->m_ctr == tc_0) {             // still marked to expire?
+                    if (t == QF_timeEvtListHead_) {
+                        QF_timeEvtListHead_ = t->m_next;
+                    }
+                    else {
+                        Q_ASSERT(prev != null_tevt);
+                        prev->m_next = t->m_next;
+                    }
+                    QF_EVT_REF_CTR_DEC_(t);                 // mark as removed
+                }
+                else {
+                    prev = t;
+                }
+            }
+            else {
+                prev = t;
+            }
+        }
+    }
+    QF_CRIT_EXIT_();
+}
+
+QP_END_
+
+// "qmp_get.cpp" =============================================================
+/// \brief QMPool::get() and QF::getPoolMargin() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+void *QMPool::get(void) {
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+
+    QFreeBlock *fb = static_cast<QFreeBlock *>(m_free);  // free block or NULL
+    if (fb != static_cast<QFreeBlock *>(0)) {         // free block available?
+        m_free = fb->m_next;        // adjust list head to the next free block
+
+        Q_ASSERT(m_nFree > static_cast<QMPoolCtr>(0));    // at least one free
+        --m_nFree;                                      // one free block less
+        if (m_nMin > m_nFree) {
+            m_nMin = m_nFree;                   // remember the minimum so far
+        }
+    }
+
+    QS_BEGIN_NOCRIT_(QS_QF_MPOOL_GET, QS::mpObj_, m_start)
+        QS_TIME_();                                               // timestamp
+        QS_OBJ_(m_start);                   // the memory managed by this pool
+        QS_MPC_(m_nFree);             // the number of free blocks in the pool
+        QS_MPC_(m_nMin);     // the mninimum number of free blocks in the pool
+    QS_END_NOCRIT_()
+
+    QF_CRIT_EXIT_();
+    return fb;               // return the block or NULL pointer to the caller
+}
+//............................................................................
+uint32_t QF::getPoolMargin(uint8_t const poolId) {
+    Q_REQUIRE((u8_1 <= poolId) && (poolId <= QF_maxPool_));
+
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+    uint32_t margin = static_cast<uint32_t>(QF_pool_[poolId - u8_1].m_nMin);
+    QF_CRIT_EXIT_();
+
+    return margin;
+}
+
+QP_END_
+
+// "qmp_init.cpp" ============================================================
+/// \brief QMPool::init() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+void QMPool::init(void * const poolSto, uint32_t const poolSize,
+                  QMPoolSize const blockSize)
+{
+    // The memory block must be valid
+    // and the poolSize must fit at least one free block
+    // and the blockSize must not be too close to the top of the dynamic range
+    Q_REQUIRE((poolSto != null_void)
+              && (poolSize >= static_cast<uint32_t>(sizeof(QFreeBlock)))
+              && ((blockSize + static_cast<QMPoolSize>(sizeof(QFreeBlock)))
+                    > blockSize));
+
+    m_free = poolSto;
+
+                // round up the blockSize to fit an integer number of pointers
+    m_blockSize = static_cast<QMPoolSize>(sizeof(QFreeBlock));//start with one
+    uint32_t nblocks = static_cast<uint32_t>(1);//# free blocks in a mem block
+    while (m_blockSize < blockSize) {
+        m_blockSize += static_cast<QMPoolSize>(sizeof(QFreeBlock));
+        ++nblocks;
+    }
+
+               // the whole pool buffer must fit at least one rounded-up block
+    Q_ASSERT(poolSize >= static_cast<uint32_t>(m_blockSize));
+
+                                // chain all blocks together in a free-list...
+                                                     // don't chain last block
+    uint32_t availSize = poolSize - static_cast<uint32_t>(m_blockSize);
+    m_nTot = static_cast<QMPoolCtr>(1);    // one (the last) block in the pool
+                                          //start at the head of the free list
+    QFreeBlock *fb = static_cast<QFreeBlock *>(m_free);
+    while (availSize >= static_cast<uint32_t>(m_blockSize)) {
+        fb->m_next = &QF_PTR_AT_(fb, nblocks);          // setup the next link
+        fb = fb->m_next;                              // advance to next block
+        availSize -= static_cast<uint32_t>(m_blockSize);// less available size
+        ++m_nTot;                     // increment the number of blocks so far
+    }
+
+    fb->m_next = static_cast<QFreeBlock *>(0); // the last link points to NULL
+    m_nFree    = m_nTot;                                // all blocks are free
+    m_nMin     = m_nTot;                  // the minimum number of free blocks
+    m_start    = poolSto;               // the original start this pool buffer
+    m_end      = fb;                            // the last block in this pool
+
+    QS_CRIT_STAT_
+    QS_BEGIN_(QS_QF_MPOOL_INIT, QS::mpObj_, m_start)
+        QS_OBJ_(m_start);                   // the memory managed by this pool
+        QS_MPC_(m_nTot);                         // the total number of blocks
+    QS_END_()
+}
+
+QP_END_
+
+// "qmp_put.cpp" =============================================================
+/// \brief QMPool::put() implementation.
+
+QP_BEGIN_
+
+// This macro is specifically and exclusively used for checking the range
+// of a block pointer returned to the pool. Such a check must rely on the
+// pointer arithmetic not compliant with the MISRA-C++:2008 rules ??? and
+// ???. Defining a specific macro for this purpose allows to selectively
+// disable the warnings for this particular case.
+//
+#define QF_PTR_RANGE_(x_, min_, max_)  (((min_) <= (x_)) && ((x_) <= (max_)))
+
+//............................................................................
+void QMPool::put(void * const b) {
+
+    Q_REQUIRE(m_nFree < m_nTot);         // adding one free so, # free < total
+    Q_REQUIRE(QF_PTR_RANGE_(b, m_start, m_end));         // b must be in range
+
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+
+                                                    // link into the free list
+    (static_cast<QFreeBlock*>(b))->m_next = static_cast<QFreeBlock *>(m_free);
+    m_free = b;                            // set as new head of the free list
+    ++m_nFree;                             // one more free block in this pool
+
+    QS_BEGIN_NOCRIT_(QS_QF_MPOOL_PUT, QS::mpObj_, m_start)
+        QS_TIME_();                                               // timestamp
+        QS_OBJ_(m_start);                   // the memory managed by this pool
+        QS_MPC_(m_nFree);             // the number of free blocks in the pool
+    QS_END_NOCRIT_()
+
+    QF_CRIT_EXIT_();
+}
+
+QP_END_
+
+
+// "qte_arm.cpp" =============================================================
+/// \brief QF_timeEvtListHead_ definition and QTimeEvt::arm_() implementation.
+
+QP_BEGIN_
+
+// Package-scope objects -----------------------------------------------------
+QTimeEvt *QF_timeEvtListHead_;           // head of linked list of time events
+
+//............................................................................
+bool QF::noTimeEvtsActive(void) {
+    return QF_timeEvtListHead_ == null_tevt;
+}
+//............................................................................
+void QTimeEvt::arm_(QActive * const act, QTimeEvtCtr const nTicks) {
+    Q_REQUIRE((nTicks > tc_0)                    /* cannot arm with 0 ticks */
+              && (act != null_act)        /* Active object must be provided */
+              && (m_ctr == tc_0)                        /* must be disarmed */
+              && (static_cast<enum_t>(sig) >= Q_USER_SIG));    // valid signal
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+    m_ctr  = nTicks;
+    m_act  = act;
+    if (refCtr_ == u8_0) {                                      // not linked?
+        m_next = QF_timeEvtListHead_;
+        QF_timeEvtListHead_ = this;
+        QF_EVT_REF_CTR_INC_(this);                           // mark as linked
+    }
+
+    QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_ARM, QS::teObj_, this)
+        QS_TIME_();                                               // timestamp
+        QS_OBJ_(this);                               // this time event object
+        QS_OBJ_(act);                                     // the active object
+        QS_TEC_(nTicks);                                // the number of ticks
+        QS_TEC_(m_interval);                                   // the interval
+    QS_END_NOCRIT_()
+
+    QF_CRIT_EXIT_();
+}
+
+QP_END_
+
+
+// "qte_ctor.cpp" ============================================================
+/// \brief QTimeEvt::QTimeEvt() implementation.
+QP_BEGIN_
+
+//............................................................................
+QTimeEvt::QTimeEvt(enum_t const s)
+  :
+#ifdef Q_EVT_CTOR
+    QEvt(static_cast<QSignal>(s)),
+#endif
+    m_next(null_tevt),
+    m_act(null_act),
+    m_ctr(tc_0),
+    m_interval(tc_0)
+{
+    Q_REQUIRE(s >= Q_USER_SIG);                        // signal must be valid
+#ifndef Q_EVT_CTOR
+    sig = static_cast<QSignal>(s);
+#endif
+                                      // time event must be static, see NOTE01
+    poolId_ = u8_0;                                 // not from any event pool
+    refCtr_ = u8_0;                                              // not linked
+}
+
+QP_END_
+
+
+// "qte_ctr.cpp" =============================================================
+/// \brief QTimeEvt::ctr() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+QTimeEvtCtr QTimeEvt::ctr(void) const {
+    QF_CRIT_STAT_
+
+    QF_CRIT_ENTRY_();
+    QTimeEvtCtr ret = m_ctr;
+
+    QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_CTR, QS::teObj_, this)
+        QS_TIME_();                                               // timestamp
+        QS_OBJ_(this);                               // this time event object
+        QS_OBJ_(m_act);                                   // the active object
+        QS_TEC_(ret);                                   // the current counter
+        QS_TEC_(m_interval);                                   // the interval
+    QS_END_NOCRIT_()
+
+    QF_CRIT_EXIT_();
+    return ret;
+}
+
+QP_END_
+
+// "qte_darm.cpp" ============================================================
+/// \brief QTimeEvt::disarm() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+// NOTE: disarm a time evt (no harm in disarming an already disarmed time evt)
+bool QTimeEvt::disarm(void) {
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+    bool wasArmed;
+    if (m_ctr != tc_0) {                  // is the time event actually armed?
+        wasArmed = true;
+
+        QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_DISARM, QS::teObj_, this)
+            QS_TIME_();                                           // timestamp
+            QS_OBJ_(this);                           // this time event object
+            QS_OBJ_(m_act);                               // the active object
+            QS_TEC_(m_ctr);                             // the number of ticks
+            QS_TEC_(m_interval);                               // the interval
+        QS_END_NOCRIT_()
+
+        m_ctr = tc_0;                        // schedule removal from the list
+    }
+    else {                                     // the time event was not armed
+        wasArmed = false;
+
+        QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_DISARM_ATTEMPT, QS::teObj_, this)
+            QS_TIME_();                                           // timestamp
+            QS_OBJ_(this);                           // this time event object
+            QS_OBJ_(m_act);                               // the active object
+        QS_END_NOCRIT_()
+    }
+    QF_CRIT_EXIT_();
+    return wasArmed;
+}
+
+QP_END_
+
+
+// "qte_rarm.cpp" ============================================================
+/// \brief QTimeEvt::rearm() implementation.
+
+QP_BEGIN_
+
+//............................................................................
+bool QTimeEvt::rearm(QTimeEvtCtr const nTicks) {
+    Q_REQUIRE((nTicks > tc_0)                  /* cannot rearm with 0 ticks */
+              && (m_act != null_act)         /* active object must be valid */
+              && (static_cast<enum_t>(sig) >= Q_USER_SIG));    // valid signal
+
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+
+    bool isArmed;
+    if (m_ctr == tc_0) {                       // is this time event disarmed?
+        isArmed = false;
+        m_next = QF_timeEvtListHead_;
+        if (QF_timeEvtListHead_ != null_tevt) {
+            m_next = QF_timeEvtListHead_;
+            QF_timeEvtListHead_ = this;
+            QF_EVT_REF_CTR_INC_(this);                       // mark as linked
+        }
+    }
+    else {
+        isArmed = true;
+    }
+    m_ctr = nTicks;            // re-load the tick counter (shift the phasing)
+
+    QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_REARM, QS::teObj_, this)
+        QS_TIME_();                                               // timestamp
+        QS_OBJ_(this);                               // this time event object
+        QS_OBJ_(m_act);                                   // the active object
+        QS_TEC_(m_ctr);                                 // the number of ticks
+        QS_TEC_(m_interval);                                   // the interval
+        QS_U8_(isArmed ? u8_1 : u8_0);                 // was the timer armed?
+    QS_END_NOCRIT_()
+
+    QF_CRIT_EXIT_();
+    return isArmed;
+}
+
+QP_END_
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Kernel selection based on QK_PREEMPTIVE
+//
+#ifdef QK_PREEMPTIVE
+
+// "qk_pkg.h" ================================================================
+/// \brief Internal (package scope) QK/C interface.
+
+#ifndef QF_CRIT_STAT_TYPE
+    /// \brief This is an internal macro for defining the critical section
+    /// status type.
+    ///
+    /// The purpose of this macro is to enable writing the same code for the
+    /// case when critical sectgion status type is defined and when it is not.
+    /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
+    /// provides the definition of the critical section status varaible.
+    /// Otherwise this macro is empty.
+    /// \sa #QF_CRIT_STAT_TYPE
+    #define QF_CRIT_STAT_
+
+    /// \brief This is an internal macro for entering a critical section.
+    ///
+    /// The purpose of this macro is to enable writing the same code for the
+    /// case when critical sectgion status type is defined and when it is not.
+    /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
+    /// invokes #QF_CRIT_ENTRY passing the key variable as the parameter.
+    /// Otherwise #QF_CRIT_ENTRY is invoked with a dummy parameter.
+    /// \sa #QF_CRIT_ENTRY
+    #define QF_CRIT_ENTRY_()    QF_CRIT_ENTRY(dummy)
+
+    /// \brief This is an internal macro for exiting a cricial section.
+    ///
+    /// The purpose of this macro is to enable writing the same code for the
+    /// case when critical sectgion status type is defined and when it is not.
+    /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
+    /// invokes #QF_CRIT_EXIT passing the key variable as the parameter.
+    /// Otherwise #QF_CRIT_EXIT is invoked with a dummy parameter.
+    /// \sa #QF_CRIT_EXIT
+    #define QF_CRIT_EXIT_()     QF_CRIT_EXIT(dummy)
+
+#else
+    #define QF_CRIT_STAT_       QF_CRIT_STAT_TYPE critStat_;
+    #define QF_CRIT_ENTRY_()    QF_CRIT_ENTRY(critStat_)
+    #define QF_CRIT_EXIT_()     QF_CRIT_EXIT(critStat_)
+#endif
+                             // define for backwards compatibility, see NOTE01
+#ifndef QF_CRIT_STAT_TYPE
+#if !defined(QF_INT_DISABLE) && defined(QF_CRIT_ENTRY)
+    #define QF_INT_DISABLE()    QF_CRIT_ENTRY(dummy)
+#endif
+#if !defined(QF_INT_ENABLE) && defined(QF_CRIT_EXIT)
+    #define QF_INT_ENABLE()     QF_CRIT_EXIT(dummy)
+#endif
+#endif                                                    // QF_CRIT_STAT_TYPE
+
+                                                   // package-scope objects...
+#ifndef QK_NO_MUTEX
+    extern "C" uint8_t QK_ceilingPrio_;         ///< QK mutex priority ceiling
+#endif
+
+// "qk.cpp" ==================================================================
+/// \brief QK_readySet_, QK_currPrio_, and QK_intNest_ definitions and
+/// QK::getVersion(), QF::init(), QF::run(), QF::stop(),
+/// QActive::start(), QActive::stop() implementations.
+
+// Public-scope objects ------------------------------------------------------
+extern "C" {
+#if (QF_MAX_ACTIVE <= 8)
+    QP_ QPSet8  QK_readySet_;                               // ready set of QK
+#else
+    QP_ QPSet64 QK_readySet_;                               // ready set of QK
+#endif
+                                         // start with the QK scheduler locked
+uint8_t QK_currPrio_ = static_cast<uint8_t>(QF_MAX_ACTIVE + 1);
+uint8_t QK_intNest_;                          // start with nesting level of 0
+
+}                                                                // extern "C"
+
+QP_BEGIN_
+
+//............................................................................
+char_t const Q_ROM * Q_ROM_VAR QK::getVersion(void) {
+    uint8_t const u8_zero = static_cast<uint8_t>('0');
+    static char_t const Q_ROM Q_ROM_VAR version[] = {
+        static_cast<char_t>(((QP_VERSION >> 12) & 0xFU) + u8_zero),
+        static_cast<char_t>('.'),
+        static_cast<char_t>(((QP_VERSION >>  8) & 0xFU) + u8_zero),
+        static_cast<char_t>('.'),
+        static_cast<char_t>(((QP_VERSION >>  4) & 0xFU) + u8_zero),
+        static_cast<char_t>((QP_VERSION         & 0xFU) + u8_zero),
+        static_cast<char_t>('\0')
+    };
+    return version;
+}
+//............................................................................
+void QF::init(void) {
+    QK_init();           // QK initialization ("C" linkage, might be assembly)
+}
+//............................................................................
+void QF::stop(void) {
+    QF::onCleanup();                                       // cleanup callback
+    // nothing else to do for the QK preemptive kernel
+}
+//............................................................................
+static void initialize(void) {
+    QK_currPrio_ = static_cast<uint8_t>(0);   // priority for the QK idle loop
+    uint8_t p = QK_schedPrio_();
+    if (p != static_cast<uint8_t>(0)) {
+        QK_sched_(p);                    // process all events produced so far
+    }
+}
+//............................................................................
+int16_t QF::run(void) {
+    QF_INT_DISABLE();
+    initialize();
+    onStartup();                                           // startup callback
+    QF_INT_ENABLE();
+
+    for (;;) {                                             // the QK idle loop
+        QK::onIdle();                        // invoke the QK on-idle callback
+    }
+                      // this unreachable return is to make the compiler happy
+    return static_cast<int16_t>(0);
+}
+//............................................................................
+void QActive::start(uint8_t const prio,
+                   QEvt const *qSto[], uint32_t const qLen,
+                   void * const stkSto, uint32_t const stkSize,
+                   QEvt const * const ie)
+{
+    Q_REQUIRE((static_cast<uint8_t>(0) < prio)
+              && (prio <= static_cast<uint8_t>(QF_MAX_ACTIVE)));
+
+    m_eQueue.init(qSto, static_cast<QEQueueCtr>(qLen));    // initialize queue
+    m_prio = prio;
+    QF::add_(this);                     // make QF aware of this active object
+
+#if defined(QK_TLS) || defined(QK_EXT_SAVE)
+    // in the QK port the parameter stkSize is used as the thread flags
+    m_osObject = static_cast<uint8_t>(stkSize);   // m_osObject contains flags
+
+    // in the QK port the parameter stkSto is used as the thread-local-storage
+    m_thread   = stkSto;   // contains the pointer to the thread-local-storage
+#else
+    Q_ASSERT((stkSto == static_cast<void *>(0))
+             && (stkSize == static_cast<uint32_t>(0)));
+#endif
+
+    init(ie);                                    // execute initial transition
+
+    QS_FLUSH();                          // flush the trace buffer to the host
+}
+//............................................................................
+void QActive::stop(void) {
+    QF::remove_(this);                // remove this active object from the QF
+}
+
+QP_END_
+
+// "qk_sched" ================================================================
+/// \brief QK_schedPrio_() and QK_sched_() implementation.
+
+//............................................................................
+// NOTE: the QK scheduler is entered and exited with interrupts DISABLED.
+// QK_sched_() is extern "C", so it does not belong to the QP namespace.
+//
+extern "C" {
+
+//............................................................................
+// NOTE: QK schedPrio_() is entered and exited with interrupts DISABLED
+uint8_t QK_schedPrio_(void) {
+
+    uint8_t p = QK_readySet_.findMax();
+
+#ifdef QK_NO_MUTEX
+    if (p > QK_currPrio_) {                        // do we have a preemption?
+#else                                   // QK priority-ceiling mutexes allowed
+    if ((p > QK_currPrio_) && (p > QK_ceilingPrio_)) {
+#endif
+    }
+    else {
+        p = static_cast<uint8_t>(0);
+    }
+    return p;
+}
+//............................................................................
+void QK_sched_(uint8_t p) {
+
+    uint8_t pin = QK_currPrio_;                   // save the initial priority
+    QP_ QActive *a;
+#ifdef QK_TLS                                    // thread-local storage used?
+    uint8_t pprev = pin;
+#endif
+    do {
+        a = QP_ QF::active_[p];                // obtain the pointer to the AO
+        QK_currPrio_ = p;            // this becomes the current task priority
+
+#ifdef QK_TLS                                    // thread-local storage used?
+        if (p != pprev) {                          // are we changing threads?
+            QK_TLS(a);                      // switch new thread-local storage
+            pprev = p;
+        }
+#endif
+        QS_BEGIN_NOCRIT_(QP_ QS_QK_SCHEDULE, QP_ QS::aoObj_, a)
+            QS_TIME_();                                           // timestamp
+            QS_U8_(p);                    // the priority of the active object
+            QS_U8_(pin);                             // the preempted priority
+        QS_END_NOCRIT_()
+
+        QF_INT_ENABLE();                  // unconditionally enable interrupts
+
+        QP_ QEvt const *e = a->get_();       // get the next event for this AO
+        a->dispatch(e);                               // dispatch e to this AO
+        QP_ QF::gc(e);              // garbage collect the event, if necessary
+
+                        // determine the next highest-priority AO ready to run
+        QF_INT_DISABLE();                                // disable interrupts
+        p = QK_readySet_.findMax();
+
+#ifdef QK_NO_MUTEX
+    } while (p > pin);             // is the new priority higher than initial?
+#else                                   // QK priority-ceiling mutexes allowed
+    } while ((p > pin) && (p > QK_ceilingPrio_));
+#endif
+
+    QK_currPrio_ = pin;                        // restore the initial priority
+
+#ifdef QK_TLS                                    // thread-local storage used?
+    if (pin != static_cast<uint8_t>(0)) { // no extended context for idle loop
+        a = QP_ QF::active_[pin];           // the pointer to the preempted AO
+        QK_TLS(a);                                 // restore the original TLS
+    }
+#endif
+}
+
+}                                                                // extern "C"
+
+#ifndef QK_NO_MUTEX
+
+// "qk_mutex.cpp" ============================================================
+/// \brief QK::mutexLock()/QK::mutexUnlock() implementation.
+
+// package-scope objects -----------------------------------------------------
+extern "C" {
+    uint8_t QK_ceilingPrio_;                    // ceiling priority of a mutex
+}
+
+QP_BEGIN_
+
+//............................................................................
+QMutex QK::mutexLock(uint8_t const prioCeiling) {
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+    uint8_t mutex = QK_ceilingPrio_; // original QK priority ceiling to return
+    if (QK_ceilingPrio_ < prioCeiling) {
+        QK_ceilingPrio_ = prioCeiling;        // raise the QK priority ceiling
+    }
+
+    QS_BEGIN_NOCRIT_(QS_QK_MUTEX_LOCK,
+                     static_cast<void *>(0), static_cast<void *>(0))
+        QS_TIME_();                                               // timestamp
+        QS_U8_(mutex);                                // the original priority
+        QS_U8_(QK_ceilingPrio_);               // the current priority ceiling
+    QS_END_NOCRIT_()
+
+    QF_CRIT_EXIT_();
+    return mutex;
+}
+//............................................................................
+void QK::mutexUnlock(QMutex mutex) {
+    QF_CRIT_STAT_
+    QF_CRIT_ENTRY_();
+
+    QS_BEGIN_NOCRIT_(QS_QK_MUTEX_UNLOCK,
+                     static_cast<void *>(0), static_cast<void *>(0))
+        QS_TIME_();                                               // timestamp
+        QS_U8_(mutex);                                // the original priority
+        QS_U8_(QK_ceilingPrio_);               // the current priority ceiling
+    QS_END_NOCRIT_()
+
+    if (QK_ceilingPrio_ > mutex) {
+        QK_ceilingPrio_ = mutex;         // restore the saved priority ceiling
+        mutex = QK_schedPrio_();             // reuse 'mutex' to hold priority
+        if (mutex != static_cast<uint8_t>(0)) {
+            QK_sched_(mutex);
+        }
+    }
+    QF_CRIT_EXIT_();
+}
+
+QP_END_
+
+#endif                                                          // QK_NO_MUTEX
+
+#else                                                         // QK_PREEMPTIVE
+
+// "qvanilla.cpp" ============================================================
+/// \brief "vanilla" cooperative kernel,
+/// QActive::start(), QActive::stop(), and QF::run() implementation.
+
+QP_BEGIN_
+
+// Package-scope objects -----------------------------------------------------
+extern "C" {
+#if (QF_MAX_ACTIVE <= 8)
+    QPSet8  QF_readySet_;                       // ready set of active objects
+#else
+    QPSet64 QF_readySet_;                       // ready set of active objects
+#endif
+
+uint8_t QF_currPrio_;                     ///< current task/interrupt priority
+uint8_t QF_intNest_;                              ///< interrupt nesting level
+
+}                                                                // extern "C"
+
+//............................................................................
+void QF::init(void) {
+    // nothing to do for the "vanilla" kernel
+}
+//............................................................................
+void QF::stop(void) {
+    onCleanup();                                           // cleanup callback
+    // nothing else to do for the "vanilla" kernel
+}
+//............................................................................
+int16_t QF::run(void) {
+    onStartup();                                           // startup callback
+
+    for (;;) {                                           // the bacground loop
+        QF_INT_DISABLE();
+        if (QF_readySet_.notEmpty()) {
+            uint8_t p = QF_readySet_.findMax();
+            QActive *a = active_[p];
+            QF_currPrio_ = p;                     // save the current priority
+            QF_INT_ENABLE();
+
+            QEvt const *e = a->get_();     // get the next event for this AO
+            a->dispatch(e);                         // dispatch evt to the HSM
+            gc(e);       // determine if event is garbage and collect it if so
+        }
+        else {
+            onIdle();                                            // see NOTE01
+        }
+    }
+                      // this unreachable return is to make the compiler happy
+    return static_cast<int16_t>(0);
+}
+//............................................................................
+void QActive::start(uint8_t const prio,
+                    QEvt const *qSto[], uint32_t const qLen,
+                    void * const stkSto, uint32_t const,
+                    QEvt const * const ie)
+{
+    Q_REQUIRE((u8_0 < prio) && (prio <= static_cast<uint8_t>(QF_MAX_ACTIVE))
+              && (stkSto == null_void));      // does not need per-actor stack
+
+    m_eQueue.init(qSto, static_cast<QEQueueCtr>(qLen));  // initialize QEQueue
+    m_prio = prio;                // set the QF priority of this active object
+    QF::add_(this);                     // make QF aware of this active object
+    init(ie);                                    // execute initial transition
+
+    QS_FLUSH();                          // flush the trace buffer to the host
+}
+//............................................................................
+void QActive::stop(void) {
+    QF::remove_(this);
+}
+
+QP_END_
+
+//////////////////////////////////////////////////////////////////////////////
+// NOTE01:
+// QF::onIdle() must be called with interrupts DISABLED because the
+// determination of the idle condition (no events in the queues) can change
+// at any time by an interrupt posting events to a queue. The QF::onIdle()
+// MUST enable interrups internally, perhaps at the same time as putting the
+// CPU into a power-saving mode.
+//
+
+extern "C" {
+
+void QK_sched_(uint8_t p) {            // dummy empty definition for qk_port.s
+    (void)p;
+}
+
+uint8_t QK_schedPrio_(void) {          // dummy empty definition for qk_port.s
+    return static_cast<uint8_t>(0U);
+}
+
+}                                                                // extern "C"
+
+#endif                                                        // QK_PREEMPTIVE
+
+//////////////////////////////////////////////////////////////////////////////
+#ifdef Q_SPY
+
+// "qs_pkg.h" ================================================================
+/// \brief Internal (package scope) QS/C++ interface.
+
+QP_BEGIN_
+
+/// \brief QS ring buffer counter and offset type
+typedef uint16_t QSCtr;
+
+/// \brief Internal QS macro to insert an un-escaped byte into
+/// the QS buffer
+////
+#define QS_INSERT_BYTE(b_) \
+    QS_PTR_AT_(QS_head_) = (b_); \
+    ++QS_head_; \
+    if (QS_head_ == QS_end_) { \
+        QS_head_ = static_cast<QSCtr>(0); \
+    } \
+    ++QS_used_;
+
+/// \brief Internal QS macro to insert an escaped byte into the QS buffer
+#define QS_INSERT_ESC_BYTE(b_) \
+    QS_chksum_ = static_cast<uint8_t>(QS_chksum_ + (b_)); \
+    if (((b_) == QS_FRAME) || ((b_) == QS_ESC)) { \
+        QS_INSERT_BYTE(QS_ESC) \
+        QS_INSERT_BYTE(static_cast<uint8_t>((b_) ^ QS_ESC_XOR)) \
+    } \
+    else { \
+        QS_INSERT_BYTE(b_) \
+    }
+
+/// \brief Internal QS macro to insert a escaped checksum byte into
+/// the QS buffer
+#define QS_INSERT_CHKSUM_BYTE() \
+    QS_chksum_ = static_cast<uint8_t>(~QS_chksum_); \
+    if ((QS_chksum_ == QS_FRAME) || (QS_chksum_ == QS_ESC)) { \
+        QS_INSERT_BYTE(QS_ESC) \
+        QS_INSERT_BYTE(static_cast<uint8_t>(QS_chksum_ ^ QS_ESC_XOR)) \
+    } \
+    else { \
+        QS_INSERT_BYTE(QS_chksum_) \
+    }
+
+
+/// \brief Internal QS macro to access the QS ring buffer
+///
+/// \note The QS buffer is allocated by the user and is accessed through the
+/// pointer QS_ring_, which violates the MISRA-C 2004 Rule 17.4(req), pointer
+/// arithmetic other than array indexing. Encapsulating this violation in a
+/// macro allows to selectively suppress this specific deviation.
+#define QS_PTR_AT_(i_) (QS_ring_[i_])
+
+
+/// \brief Frame character of the QS output protocol
+uint8_t const QS_FRAME = static_cast<uint8_t>(0x7E);
+
+/// \brief Escape character of the QS output protocol
+uint8_t const QS_ESC   = static_cast<uint8_t>(0x7D);
+
+/// \brief Escape modifier of the QS output protocol
+///
+/// The escaped byte is XOR-ed with the escape modifier before it is inserted
+/// into the QS buffer.
+uint8_t const QS_ESC_XOR = static_cast<uint8_t>(0x20);
+
+#ifndef Q_ROM_BYTE
+    /// \brief Macro to access a byte allocated in ROM
+    ///
+    /// Some compilers for Harvard-architecture MCUs, such as gcc for AVR, do
+    /// not generate correct code for accessing data allocated in the program
+    /// space (ROM). The workaround for such compilers is to explictly add
+    /// assembly code to access each data element allocated in the program
+    /// space. The macro Q_ROM_BYTE() retrieves a byte from the given ROM
+    /// address.
+    ///
+    /// The Q_ROM_BYTE() macro should be defined for the compilers that
+    /// cannot handle correctly data allocated in ROM (such as the gcc).
+    /// If the macro is left undefined, the default definition simply returns
+    /// the argument and lets the compiler generate the correct code.
+    #define Q_ROM_BYTE(rom_var_)   (rom_var_)
+#endif
+
+//............................................................................
+extern uint8_t *QS_ring_;         ///< pointer to the start of the ring buffer
+extern QSCtr QS_end_;                ///< offset of the end of the ring buffer
+extern QSCtr QS_head_;         ///< offset to where next byte will be inserted
+extern QSCtr QS_tail_;       ///< offset of where next event will be extracted
+extern QSCtr QS_used_;       ///< number of bytes currently in the ring buffer
+extern uint8_t QS_seq_;                        ///< the record sequence number
+extern uint8_t QS_chksum_;             ///< the checksum of the current record
+extern uint8_t QS_full_;              ///< the ring buffer is temporarily full
+
+QP_END_
+
+
+// "qs.cpp" ==================================================================
+/// \brief QS internal variables definitions and core QS functions
+/// implementations.
+
+QP_BEGIN_
+
+//............................................................................
+uint8_t QS::glbFilter_[32];                                // global QS filter
+
+//............................................................................
+uint8_t *QS_ring_;                  // pointer to the start of the ring buffer
+QSCtr QS_end_;                         // offset of the end of the ring buffer
+QSCtr QS_head_;                  // offset to where next byte will be inserted
+QSCtr QS_tail_;                 // offset of where next byte will be extracted
+QSCtr QS_used_;                // number of bytes currently in the ring buffer
+uint8_t QS_seq_;                                 // the record sequence number
+uint8_t QS_chksum_;                      // the checksum of the current record
+uint8_t QS_full_;                       // the ring buffer is temporarily full
+
+//............................................................................
+char_t const Q_ROM * Q_ROM_VAR QS::getVersion(void) {
+    uint8_t const u8_zero = static_cast<uint8_t>('0');
+    static char_t const Q_ROM Q_ROM_VAR version[] = {
+        static_cast<char_t>(((QP_VERSION >> 12) & 0xFU) + u8_zero),
+        static_cast<char_t>('.'),
+        static_cast<char_t>(((QP_VERSION >>  8) & 0xFU) + u8_zero),
+        static_cast<char_t>('.'),
+        static_cast<char_t>(((QP_VERSION >>  4) & 0xFU) + u8_zero),
+        static_cast<char_t>((QP_VERSION         & 0xFU) + u8_zero),
+        static_cast<char_t>('\0')
+    };
+    return version;
+}
+//............................................................................
+void QS::initBuf(uint8_t sto[], uint32_t const stoSize) {
+    QS_ring_ = &sto[0];
+    QS_end_  = static_cast<QSCtr>(stoSize);
+}
+//............................................................................
+void QS::filterOn(uint8_t const rec) {
+    if (rec == QS_ALL_RECORDS) {
+        uint8_t i;
+        for (i = static_cast<uint8_t>(0);
+             i < static_cast<uint8_t>(sizeof(glbFilter_));
+             ++i)
+        {
+            glbFilter_[i] = static_cast<uint8_t>(0xFF);
+        }
+    }
+    else {
+        glbFilter_[rec >> 3] |=
+            static_cast<uint8_t>(1U << (rec & static_cast<uint8_t>(0x07)));
+    }
+}
+//............................................................................
+void QS::filterOff(uint8_t const rec) {
+    if (rec == QS_ALL_RECORDS) {
+        uint8_t i;
+        for (i = static_cast<uint8_t>(0);
+            i < static_cast<uint8_t>(sizeof(glbFilter_));
+            ++i)
+        {
+            glbFilter_[i] = static_cast<uint8_t>(0);
+        }
+    }
+    else {
+        glbFilter_[rec >> 3] &= static_cast<uint8_t>(
+           ~static_cast<uint8_t>((1U << (rec & static_cast<uint8_t>(0x07)))));
+    }
+}
+//............................................................................
+void QS::begin(uint8_t const rec) {
+    QS_chksum_ = static_cast<uint8_t>(0);                // clear the checksum
+    ++QS_seq_;                         // always increment the sequence number
+    QS_INSERT_ESC_BYTE(QS_seq_)                   // store the sequence number
+    QS_INSERT_ESC_BYTE(rec)                             // store the record ID
+}
+//............................................................................
+void QS::end(void) {
+    QS_INSERT_CHKSUM_BYTE()
+    QS_INSERT_BYTE(QS_FRAME)
+    if (QS_used_ > QS_end_) {                    // overrun over the old data?
+        QS_tail_ = QS_head_;                 // shift the tail to the old data
+        QS_used_ = QS_end_;                        // the whole buffer is used
+    }
+}
+//............................................................................
+void QS::u8(uint8_t const format, uint8_t const d) {
+    QS_INSERT_ESC_BYTE(format)
+    QS_INSERT_ESC_BYTE(d)
+}
+//............................................................................
+void QS::u16(uint8_t const format, uint16_t d) {
+    QS_INSERT_ESC_BYTE(format)
+    QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
+    d >>= 8;
+    QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
+}
+//............................................................................
+void QS::u32(uint8_t const format, uint32_t d) {
+    QS_INSERT_ESC_BYTE(format)
+    QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
+    d >>= 8;
+    QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
+    d >>= 8;
+    QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
+    d >>= 8;
+    QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
+}
+
+QP_END_
+
+
+// "qs_.cpp" =================================================================
+/// \brief QS functions for internal use inside QP components
+
+QP_BEGIN_
+
+//............................................................................
+void const *QS::smObj_;                  // local state machine for QEP filter
+void const *QS::aoObj_;                   // local active object for QF filter
+void const *QS::mpObj_;                     //  local event pool for QF filter
+void const *QS::eqObj_;                      //  local raw queue for QF filter
+void const *QS::teObj_;                     //  local time event for QF filter
+void const *QS::apObj_;                    //  local object Application filter
+
+QSTimeCtr QS::tickCtr_;              // tick counter for the QS_QF_TICK record
+
+//............................................................................
+void QS::u8_(uint8_t const d) {
+    QS_INSERT_ESC_BYTE(d)
+}
+//............................................................................
+void QS::u16_(uint16_t d) {
+    QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
+    d >>= 8;
+    QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
+}
+//............................................................................
+void QS::u32_(uint32_t d) {
+    QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
+    d >>= 8;
+    QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
+    d >>= 8;
+    QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
+    d >>= 8;
+    QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
+}
+//............................................................................
+void QS::str_(char_t const *s) {
+    uint8_t b = static_cast<uint8_t>(*s);
+    while (b != static_cast<uint8_t>(0)) {
+                                       // ASCII characters don't need escaping
+        QS_chksum_ = static_cast<uint8_t>(QS_chksum_ + b);
+        QS_INSERT_BYTE(b)
+        ++s;
+        b = static_cast<uint8_t>(*s);
+    }
+    QS_INSERT_BYTE(static_cast<uint8_t>(0))
+}
+//............................................................................
+void QS::str_ROM_(char_t const Q_ROM * Q_ROM_VAR s) {
+    uint8_t b = static_cast<uint8_t>(Q_ROM_BYTE(*s));
+    while (b != static_cast<uint8_t>(0)) {
+                                       // ASCII characters don't need escaping
+        QS_chksum_ = static_cast<uint8_t>(QS_chksum_ + b);
+        QS_INSERT_BYTE(b)
+        ++s;
+        b = static_cast<uint8_t>(Q_ROM_BYTE(*s));
+    }
+    QS_INSERT_BYTE(static_cast<uint8_t>(0))
+}
+
+QP_END_
+
+// "qs_blk.cpp" ==============================================================
+/// \brief QS::getBlock() implementation
+
+QP_BEGIN_
+
+//............................................................................
+// get up to *pn bytes of contiguous memory
+uint8_t const *QS::getBlock(uint16_t * const pNbytes) {
+    uint8_t *block;
+    if (QS_used_ == static_cast<QSCtr>(0)) {
+        *pNbytes = static_cast<uint16_t>(0);
+        block = static_cast<uint8_t *>(0);     // no bytes to return right now
+    }
+    else {
+        QSCtr n = static_cast<QSCtr>(QS_end_ - QS_tail_);
+        if (n > QS_used_) {
+            n = QS_used_;
+        }
+        if (n > static_cast<QSCtr>(*pNbytes)) {
+            n = static_cast<QSCtr>(*pNbytes);
+        }
+        *pNbytes = static_cast<uint16_t>(n);
+        QS_used_ = static_cast<QSCtr>(QS_used_ - n);
+        QSCtr t  = QS_tail_;
+        QS_tail_ = static_cast<QSCtr>(QS_tail_ + n);
+        if (QS_tail_ == QS_end_) {
+            QS_tail_ = static_cast<QSCtr>(0);
+        }
+        block = &QS_PTR_AT_(t);
+    }
+    return block;
+}
+
+QP_END_
+
+// "qs_byte.cpp" =============================================================
+/// \brief QS::getByte() implementation
+
+QP_BEGIN_
+
+//............................................................................
+uint16_t QS::getByte(void) {
+    uint16_t ret;
+    if (QS_used_ == static_cast<QSCtr>(0)) {
+        ret = QS_EOD;                                       // set End-Of-Data
+    }
+    else {
+        ret = static_cast<uint16_t>(QS_PTR_AT_(QS_tail_));   // byte to return
+        ++QS_tail_;                                        // advance the tail
+        if (QS_tail_ == QS_end_) {                        // tail wrap around?
+            QS_tail_ = static_cast<QSCtr>(0);
+        }
+        --QS_used_;                                      // one less byte used
+    }
+    return ret;                                      // return the byte or EOD
+}
+
+QP_END_
+
+
+// "qs_f32.cpp" ==============================================================
+/// \brief QS::f32() implementation
+
+QP_BEGIN_
+
+//............................................................................
+void QS::f32(uint8_t const format, float32_t const d) {
+    union F32Rep {
+        float32_t f;
+        uint32_t  u;
+    } fu32;
+    fu32.f = d;
+
+    QS_INSERT_ESC_BYTE(format)
+    QS_INSERT_ESC_BYTE(static_cast<uint8_t>(fu32.u))
+    fu32.u >>= 8;
+    QS_INSERT_ESC_BYTE(static_cast<uint8_t>(fu32.u))
+    fu32.u >>= 8;
+    QS_INSERT_ESC_BYTE(static_cast<uint8_t>(fu32.u))
+    fu32.u >>= 8;
+    QS_INSERT_ESC_BYTE(static_cast<uint8_t>(fu32.u))
+}
+
+QP_END_
+
+
+// "qs_mem.cpp" ==============================================================
+/// \brief QS::mem() implementation
+
+QP_BEGIN_
+
+//............................................................................
+void QS::mem(uint8_t const *blk, uint8_t size) {
+    QS_INSERT_BYTE(static_cast<uint8_t>(QS_MEM_T))
+    QS_chksum_ =
+        static_cast<uint8_t>(QS_chksum_ + static_cast<uint8_t>(QS_MEM_T));
+    QS_INSERT_ESC_BYTE(size)
+    while (size != static_cast<uint8_t>(0)) {
+        QS_INSERT_ESC_BYTE(*blk)
+        ++blk;
+        --size;
+    }
+}
+
+QP_END_
+
+
+// "qs_str.cpp" ==============================================================
+/// \brief QS::str() and QS::str_ROM() implementation
+
+QP_BEGIN_
+
+//............................................................................
+void QS::str(char_t const *s) {
+    uint8_t b = static_cast<uint8_t>(*s);
+    QS_INSERT_BYTE(static_cast<uint8_t>(QS_STR_T))
+    QS_chksum_ =
+        static_cast<uint8_t>(QS_chksum_ + static_cast<uint8_t>(QS_STR_T));
+    while (b != static_cast<uint8_t>(0)) {
+                                       // ASCII characters don't need escaping
+        QS_INSERT_BYTE(b)
+        QS_chksum_ = static_cast<uint8_t>(QS_chksum_ + b);
+        ++s;
+        b = static_cast<uint8_t>(*s);
+    }
+    QS_INSERT_BYTE(static_cast<uint8_t>(0))
+}
+//............................................................................
+void QS::str_ROM(char_t const Q_ROM * Q_ROM_VAR s) {
+    uint8_t b = static_cast<uint8_t>(Q_ROM_BYTE(*s));
+    QS_INSERT_BYTE(static_cast<uint8_t>(QS_STR_T))
+    QS_chksum_ =
+        static_cast<uint8_t>(QS_chksum_ + static_cast<uint8_t>(QS_STR_T));
+    while (b != static_cast<uint8_t>(0)) {
+                                       // ASCII characters don't need escaping
+        QS_INSERT_BYTE(b)
+        QS_chksum_ = static_cast<uint8_t>(QS_chksum_ + b);
+        ++s;
+        b = static_cast<uint8_t>(Q_ROM_BYTE(*s));
+    }
+    QS_INSERT_BYTE(static_cast<uint8_t>(0))
+}
+
+QP_END_
+
+#endif                                                                // Q_SPY