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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers qp.cpp Source File

qp.cpp

00001 //////////////////////////////////////////////////////////////////////////////
00002 // Product: QP/C++
00003 // Last Updated for QP ver: 4.5.02 (modified to fit in one file)
00004 // Date of the Last Update: Aug 24, 2012
00005 //
00006 //                    Q u a n t u m     L e a P s
00007 //                    ---------------------------
00008 //                    innovating embedded systems
00009 //
00010 // Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved.
00011 //
00012 // This program is open source software: you can redistribute it and/or
00013 // modify it under the terms of the GNU General Public License as published
00014 // by the Free Software Foundation, either version 2 of the License, or
00015 // (at your option) any later version.
00016 //
00017 // Alternatively, this program may be distributed and modified under the
00018 // terms of Quantum Leaps commercial licenses, which expressly supersede
00019 // the GNU General Public License and are specifically designed for
00020 // licensees interested in retaining the proprietary status of their code.
00021 //
00022 // This program is distributed in the hope that it will be useful,
00023 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00024 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00025 // GNU General Public License for more details.
00026 //
00027 // You should have received a copy of the GNU General Public License
00028 // along with this program. If not, see <http://www.gnu.org/licenses/>.
00029 //
00030 // Contact information:
00031 // Quantum Leaps Web sites: http://www.quantum-leaps.com
00032 //                          http://www.state-machine.com
00033 // e-mail:                  info@quantum-leaps.com
00034 //////////////////////////////////////////////////////////////////////////////
00035 #include "qp_port.h"                                                // QP port
00036 
00037 // "qep_pkg.h" ===============================================================
00038 QP_BEGIN_
00039 
00040 Q_DEFINE_THIS_MODULE("qp")
00041 
00042 //////////////////////////////////////////////////////////////////////////////
00043 /// preallocated reserved events
00044 extern QEvt const QEP_reservedEvt_[];
00045 
00046 /// empty signal for internal use only
00047 QSignal const QEP_EMPTY_SIG_ = static_cast<QSignal>(0);
00048 
00049 /// maximum depth of state nesting (including the top level), must be >= 3
00050 int8_t const QEP_MAX_NEST_DEPTH_ = static_cast<int8_t>(6);
00051 
00052 uint8_t const u8_0  = static_cast<uint8_t>(0); ///< \brief constant (uint8_t)0
00053 uint8_t const u8_1  = static_cast<uint8_t>(1); ///< \brief constant (uint8_t)1
00054 int8_t  const s8_0  = static_cast<int8_t>(0);  ///< \brief constant  (int8_t)0
00055 int8_t  const s8_1  = static_cast<int8_t>(1);  ///< \brief constant  (int8_t)1
00056 int8_t  const s8_n1 = static_cast<int8_t>(-1); ///< \brief constant (int8_t)-1
00057 
00058 QP_END_
00059 
00060 /// helper macro to trigger internal event in an HSM
00061 #define QEP_TRIG_(state_, sig_) \
00062     ((*(state_))(this, &QEP_reservedEvt_[sig_]))
00063 
00064 /// helper macro to trigger exit action in an HSM
00065 #define QEP_EXIT_(state_) do { \
00066     if (QEP_TRIG_(state_, Q_EXIT_SIG) == Q_RET_HANDLED) { \
00067         QS_BEGIN_(QS_QEP_STATE_EXIT, QS::smObj_, this) \
00068             QS_OBJ_(this); \
00069             QS_FUN_(state_); \
00070         QS_END_() \
00071     } \
00072 } while (false)
00073 
00074 /// helper macro to trigger entry action in an HSM
00075 #define QEP_ENTER_(state_) do { \
00076     if (QEP_TRIG_(state_, Q_ENTRY_SIG) == Q_RET_HANDLED) { \
00077         QS_BEGIN_(QS_QEP_STATE_ENTRY, QS::smObj_, this) \
00078             QS_OBJ_(this); \
00079             QS_FUN_(state_); \
00080         QS_END_() \
00081     } \
00082 } while (false)
00083 
00084 // "qep.cpp" =================================================================
00085 /// \brief ::QEP_reservedEvt_ definition and QEP::getVersion() implementation.
00086 
00087 QP_BEGIN_
00088 
00089 // Package-scope objects -----------------------------------------------------
00090 QEvt const QEP_reservedEvt_[] = {
00091 #ifdef Q_EVT_CTOR                         // Is the QEvt constructor provided?
00092     static_cast<QSignal>(0),
00093     static_cast<QSignal>(1),
00094     static_cast<QSignal>(2),
00095     static_cast<QSignal>(3)
00096 #else                                    // QEvt is a POD (Plain Old Datatype)
00097     { static_cast<QSignal>(0), u8_0, u8_0 },
00098     { static_cast<QSignal>(1), u8_0, u8_0 },
00099     { static_cast<QSignal>(2), u8_0, u8_0 },
00100     { static_cast<QSignal>(3), u8_0, u8_0 }
00101 #endif
00102 };
00103 //............................................................................
00104 char_t const Q_ROM * Q_ROM_VAR QEP::getVersion(void) {
00105     uint8_t const u8_zero = static_cast<uint8_t>('0');
00106     static char_t const Q_ROM Q_ROM_VAR version[] = {
00107         static_cast<char_t>(((QP_VERSION >> 12) & 0xFU) + u8_zero),
00108         static_cast<char_t>('.'),
00109         static_cast<char_t>(((QP_VERSION >>  8) & 0xFU) + u8_zero),
00110         static_cast<char_t>('.'),
00111         static_cast<char_t>(((QP_VERSION >>  4) & 0xFU) + u8_zero),
00112         static_cast<char_t>((QP_VERSION         & 0xFU) + u8_zero),
00113         static_cast<char_t>('\0')
00114     };
00115     return version;
00116 }
00117 
00118 QP_END_
00119 
00120 // "qhsm_top.cpp" ============================================================
00121 /// \brief QHsm::top() implementation.
00122 
00123 QP_BEGIN_
00124 
00125 //............................................................................
00126 QState QHsm::top(void * const, QEvt const * const) {
00127     return Q_RET_IGNORED;                  // the top state ignores all events
00128 }
00129 
00130 QP_END_
00131 
00132 // "qhsm_ini.cpp" ============================================================
00133 /// \brief QHsm::init() implementation.
00134 
00135 QP_BEGIN_
00136 
00137 //............................................................................
00138 QHsm::~QHsm() {
00139 }
00140 //............................................................................
00141 void QHsm::init(QEvt const * const e) {
00142     QStateHandler t = m_state;
00143 
00144     Q_REQUIRE((m_temp != Q_STATE_CAST(0))             // ctor must be executed
00145               && (t == Q_STATE_CAST(&QHsm::top)));  // initial tran. NOT taken
00146 
00147                               // the top-most initial transition must be taken
00148     Q_ALLEGE((*m_temp)(this, e) == Q_RET_TRAN);
00149 
00150     QS_CRIT_STAT_
00151     do {                                           // drill into the target...
00152         QStateHandler path[QEP_MAX_NEST_DEPTH_];
00153         int8_t ip = s8_0;                       // transition entry path index
00154 
00155         QS_BEGIN_(QS_QEP_STATE_INIT, QS::smObj_, this)
00156             QS_OBJ_(this);                        // this state machine object
00157             QS_FUN_(t);                                    // the source state
00158             QS_FUN_(m_temp);           // the target of the initial transition
00159         QS_END_()
00160 
00161         path[0] = m_temp;
00162         (void)QEP_TRIG_(m_temp, QEP_EMPTY_SIG_);
00163         while (m_temp != t) {
00164             ++ip;
00165             path[ip] = m_temp;
00166             (void)QEP_TRIG_(m_temp, QEP_EMPTY_SIG_);
00167         }
00168         m_temp = path[0];
00169                                                // entry path must not overflow
00170         Q_ASSERT(ip < QEP_MAX_NEST_DEPTH_);
00171 
00172         do {           // retrace the entry path in reverse (desired) order...
00173             QEP_ENTER_(path[ip]);                            // enter path[ip]
00174             --ip;
00175         } while (ip >= s8_0);
00176 
00177         t = path[0];                   // current state becomes the new source
00178     } while (QEP_TRIG_(t, Q_INIT_SIG) == Q_RET_TRAN);
00179 
00180     QS_BEGIN_(QS_QEP_INIT_TRAN, QS::smObj_, this)
00181         QS_TIME_();                                              // time stamp
00182         QS_OBJ_(this);                            // this state machine object
00183         QS_FUN_(t);                                    // the new active state
00184     QS_END_()
00185 
00186     m_state = t;                            // change the current active state
00187     m_temp  = t;                           // mark the configuration as stable
00188 }
00189 
00190 QP_END_
00191 
00192 // "qhsm_dis.cpp" ============================================================
00193 /// \brief QHsm::dispatch() implementation.
00194 
00195 QP_BEGIN_
00196 
00197 //............................................................................
00198 void QHsm::dispatch(QEvt const * const e) {
00199     QStateHandler t = m_state;
00200 
00201     Q_REQUIRE(t == m_temp);          // the state configuration must be stable
00202 
00203     QStateHandler s;
00204     QState r;
00205     QS_CRIT_STAT_
00206 
00207     QS_BEGIN_(QS_QEP_DISPATCH, QS::smObj_, this)
00208         QS_TIME_();                                              // time stamp
00209         QS_SIG_(e->sig);                            // the signal of the event
00210         QS_OBJ_(this);                            // this state machine object
00211         QS_FUN_(t);                                       // the current state
00212     QS_END_()
00213 
00214     do {                                // process the event hierarchically...
00215         s = m_temp;
00216         r = (*s)(this, e);                           // invoke state handler s
00217 
00218         if (r == Q_RET_UNHANDLED) {               // unhandled due to a guard?
00219 
00220             QS_BEGIN_(QS_QEP_UNHANDLED, QS::smObj_, this)
00221                 QS_SIG_(e->sig);                    // the signal of the event
00222                 QS_OBJ_(this);                    // this state machine object
00223                 QS_FUN_(s);                               // the current state
00224             QS_END_()
00225 
00226             r = QEP_TRIG_(s, QEP_EMPTY_SIG_);          // find superstate of s
00227         }
00228     } while (r == Q_RET_SUPER);
00229 
00230     if (r == Q_RET_TRAN) {                                // transition taken?
00231         QStateHandler path[QEP_MAX_NEST_DEPTH_];
00232         int8_t ip = s8_n1;                      // transition entry path index
00233         int8_t iq;                       // helper transition entry path index
00234 #ifdef Q_SPY
00235         QStateHandler src = s;       // save the transition source for tracing
00236 #endif
00237 
00238         path[0] = m_temp;                 // save the target of the transition
00239         path[1] = t;
00240 
00241         while (t != s) {       // exit current state to transition source s...
00242             if (QEP_TRIG_(t, Q_EXIT_SIG) == Q_RET_HANDLED) {   //exit handled?
00243                 QS_BEGIN_(QS_QEP_STATE_EXIT, QS::smObj_, this)
00244                     QS_OBJ_(this);                // this state machine object
00245                     QS_FUN_(t);                            // the exited state
00246                 QS_END_()
00247 
00248                 (void)QEP_TRIG_(t, QEP_EMPTY_SIG_);    // find superstate of t
00249             }
00250             t = m_temp;                         // m_temp holds the superstate
00251         }
00252 
00253         t = path[0];                               // target of the transition
00254 
00255         if (s == t) {         // (a) check source==target (transition to self)
00256             QEP_EXIT_(s);                                   // exit the source
00257             ip = s8_0;                                     // enter the target
00258         }
00259         else {
00260             (void)QEP_TRIG_(t, QEP_EMPTY_SIG_);        // superstate of target
00261             t = m_temp;
00262             if (s == t) {                   // (b) check source==target->super
00263                 ip = s8_0;               // enter the target
00264             }
00265             else {
00266                 (void)QEP_TRIG_(s, QEP_EMPTY_SIG_);       // superstate of src
00267                                      // (c) check source->super==target->super
00268                 if (m_temp == t) {
00269                     QEP_EXIT_(s);                           // exit the source
00270                     ip = s8_0;           // enter the target
00271                 }
00272                 else {
00273                                             // (d) check source->super==target
00274                     if (m_temp == path[0]) {
00275                         QEP_EXIT_(s);                       // exit the source
00276                     }
00277                     else { // (e) check rest of source==target->super->super..
00278                            // and store the entry path along the way
00279                            //
00280                         iq = s8_0; // indicate LCA not found
00281                         ip = s8_1; // enter target's superst
00282                         path[1] = t;          // save the superstate of target
00283                         t = m_temp;                      // save source->super
00284                                                   // find target->super->super
00285                         r = QEP_TRIG_(path[1], QEP_EMPTY_SIG_);
00286                         while (r == Q_RET_SUPER) {
00287                             ++ip;
00288                             path[ip] = m_temp;         // store the entry path
00289                             if (m_temp == s) {            // is it the source?
00290                                                     // indicate that LCA found
00291                                 iq = s8_1;
00292                                                // entry path must not overflow
00293                                 Q_ASSERT(ip < QEP_MAX_NEST_DEPTH_);
00294                                 --ip;               // do not enter the source
00295                                 r = Q_RET_HANDLED;       // terminate the loop
00296                             }
00297                             else {      // it is not the source, keep going up
00298                                 r = QEP_TRIG_(m_temp, QEP_EMPTY_SIG_);
00299                             }
00300                         }
00301                         if (iq == s8_0) {  // LCA found yet?
00302 
00303                                                // entry path must not overflow
00304                             Q_ASSERT(ip < QEP_MAX_NEST_DEPTH_);
00305 
00306                             QEP_EXIT_(s);                   // exit the source
00307 
00308                             // (f) check the rest of source->super
00309                             //                  == target->super->super...
00310                             //
00311                             iq = ip;
00312                             r = Q_RET_IGNORED;       // indicate LCA NOT found
00313                             do {
00314                                 if (t == path[iq]) {       // is this the LCA?
00315                                     r = Q_RET_HANDLED;   // indicate LCA found
00316                                                            // do not enter LCA
00317                                     ip = static_cast<int8_t>(iq - s8_1);
00318                                                          // terminate the loop
00319                                     iq = s8_n1;
00320                                 }
00321                                 else {
00322                                     --iq;    // try lower superstate of target
00323                                 }
00324                             } while (iq >= s8_0);
00325 
00326                             if (r != Q_RET_HANDLED) {    // LCA not found yet?
00327                                 // (g) check each source->super->...
00328                                 // for each target->super...
00329                                 //
00330                                 r = Q_RET_IGNORED;             // keep looping
00331                                 do {
00332                                                           // exit t unhandled?
00333                                     if (QEP_TRIG_(t, Q_EXIT_SIG)
00334                                         == Q_RET_HANDLED)
00335                                     {
00336                                         QS_BEGIN_(QS_QEP_STATE_EXIT,
00337                                                   QS::smObj_, this)
00338                                             QS_OBJ_(this);
00339                                             QS_FUN_(t);
00340                                         QS_END_()
00341 
00342                                         (void)QEP_TRIG_(t, QEP_EMPTY_SIG_);
00343                                     }
00344                                     t = m_temp;          //  set to super of t
00345                                     iq = ip;
00346                                     do {
00347                                         if (t == path[iq]) {   // is this LCA?
00348                                                            // do not enter LCA
00349                                             ip = static_cast<int8_t>(iq-s8_1);
00350                                                 // break out of the inner loop
00351                                             iq = s8_n1;
00352                                             r = Q_RET_HANDLED;  // break outer
00353                                         }
00354                                         else {
00355                                             --iq;
00356                                         }
00357                                     } while (iq >= s8_0);
00358                                 } while (r != Q_RET_HANDLED);
00359                             }
00360                         }
00361                     }
00362                 }
00363             }
00364         }
00365                        // retrace the entry path in reverse (desired) order...
00366         for (; ip >= s8_0; --ip) {
00367             QEP_ENTER_(path[ip]);                            // enter path[ip]
00368         }
00369         t = path[0];                         // stick the target into register
00370         m_temp = t;                                   // update the next state
00371 
00372                                          // drill into the target hierarchy...
00373         while (QEP_TRIG_(t, Q_INIT_SIG) == Q_RET_TRAN) {
00374 
00375             QS_BEGIN_(QS_QEP_STATE_INIT, QS::smObj_, this)
00376                 QS_OBJ_(this);                    // this state machine object
00377                 QS_FUN_(t);                        // the source (pseudo)state
00378                 QS_FUN_(m_temp);              // the target of the transition
00379             QS_END_()
00380 
00381             ip = s8_0;
00382             path[0] = m_temp;
00383             (void)QEP_TRIG_(m_temp, QEP_EMPTY_SIG_);       // find superstate
00384             while (m_temp != t) {
00385                 ++ip;
00386                 path[ip] = m_temp;
00387                 (void)QEP_TRIG_(m_temp, QEP_EMPTY_SIG_);   // find superstate
00388             }
00389             m_temp = path[0];
00390                                                // entry path must not overflow
00391             Q_ASSERT(ip < QEP_MAX_NEST_DEPTH_);
00392 
00393             do {       // retrace the entry path in reverse (correct) order...
00394                 QEP_ENTER_(path[ip]);                        // enter path[ip]
00395                 --ip;
00396             } while (ip >= s8_0);
00397 
00398             t = path[0];
00399         }
00400 
00401         QS_BEGIN_(QS_QEP_TRAN, QS::smObj_, this)
00402             QS_TIME_();                                          // time stamp
00403             QS_SIG_(e->sig);                        // the signal of the event
00404             QS_OBJ_(this);                        // this state machine object
00405             QS_FUN_(src);                      // the source of the transition
00406             QS_FUN_(t);                                // the new active state
00407         QS_END_()
00408 
00409     }
00410     else {                                             // transition not taken
00411 #ifdef Q_SPY
00412         if (r == Q_RET_HANDLED) {
00413 
00414             QS_BEGIN_(QS_QEP_INTERN_TRAN, QS::smObj_, this)
00415                 QS_TIME_();                                      // time stamp
00416                 QS_SIG_(e->sig);                    // the signal of the event
00417                 QS_OBJ_(this);                    // this state machine object
00418                 QS_FUN_(m_state);          // the state that handled the event
00419             QS_END_()
00420 
00421         }
00422         else {
00423 
00424             QS_BEGIN_(QS_QEP_IGNORED, QS::smObj_, this)
00425                 QS_TIME_();                                      // time stamp
00426                 QS_SIG_(e->sig);                    // the signal of the event
00427                 QS_OBJ_(this);                    // this state machine object
00428                 QS_FUN_(m_state);                         // the current state
00429             QS_END_()
00430 
00431         }
00432 #endif
00433     }
00434 
00435     m_state = t;                            // change the current active state
00436     m_temp  = t;                           // mark the configuration as stable
00437 }
00438 
00439 QP_END_
00440 
00441 // "qf_pkg.h" ================================================================
00442 /// \brief Internal (package scope) QF/C++ interface.
00443 
00444 /// \brief helper macro to cast const away from an event pointer \a e_
00445 #define QF_EVT_CONST_CAST_(e_) const_cast<QEvt *>(e_)
00446 
00447 QP_BEGIN_
00448                                                // QF-specific critical section
00449 #ifndef QF_CRIT_STAT_TYPE
00450     /// \brief This is an internal macro for defining the critical section
00451     /// status type.
00452     ///
00453     /// The purpose of this macro is to enable writing the same code for the
00454     /// case when critical sectgion status type is defined and when it is not.
00455     /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
00456     /// provides the definition of the critical section status varaible.
00457     /// Otherwise this macro is empty.
00458     /// \sa #QF_CRIT_STAT_TYPE
00459     ///
00460     #define QF_CRIT_STAT_
00461 
00462     /// \brief This is an internal macro for entering a critical section.
00463     ///
00464     /// The purpose of this macro is to enable writing the same code for the
00465     /// case when critical sectgion status type is defined and when it is not.
00466     /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
00467     /// invokes #QF_CRIT_ENTRY passing the key variable as the parameter.
00468     /// Otherwise #QF_CRIT_ENTRY is invoked with a dummy parameter.
00469     /// \sa #QF_CRIT_ENTRY
00470     ///
00471     #define QF_CRIT_ENTRY_()    QF_CRIT_ENTRY(dummy)
00472 
00473     /// \brief This is an internal macro for exiting a cricial section.
00474     ///
00475     /// The purpose of this macro is to enable writing the same code for the
00476     /// case when critical sectgion status type is defined and when it is not.
00477     /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
00478     /// invokes #QF_CRIT_EXIT passing the key variable as the parameter.
00479     /// Otherwise #QF_CRIT_EXIT is invoked with a dummy parameter.
00480     /// \sa #QF_CRIT_EXIT
00481     ///
00482     #define QF_CRIT_EXIT_()     QF_CRIT_EXIT(dummy)
00483 
00484 #else
00485     #define QF_CRIT_STAT_       QF_CRIT_STAT_TYPE critStat_;
00486     #define QF_CRIT_ENTRY_()    QF_CRIT_ENTRY(critStat_)
00487     #define QF_CRIT_EXIT_()     QF_CRIT_EXIT(critStat_)
00488 #endif
00489 
00490 // package-scope objects -----------------------------------------------------
00491 extern QTimeEvt *QF_timeEvtListHead_;  ///< head of linked list of time events
00492 extern QF_EPOOL_TYPE_ QF_pool_[QF_MAX_EPOOL];        ///< allocate event pools
00493 extern uint8_t QF_maxPool_;                  ///< # of initialized event pools
00494 extern QSubscrList *QF_subscrList_;             ///< the subscriber list array
00495 extern enum_t QF_maxSignal_;                 ///< the maximum published signal
00496 
00497 //............................................................................
00498 /// \brief Structure representing a free block in the Native QF Memory Pool
00499 /// \sa ::QMPool
00500 struct QFreeBlock {
00501     QFreeBlock *m_next;
00502 };
00503 
00504 //////////////////////////////////////////////////////////////////////////////
00505 // internal helper inline functions
00506 
00507 /// \brief access to the poolId_ of an event \a e
00508 inline uint8_t QF_EVT_POOL_ID_(QEvt const * const e) { return e->poolId_; }
00509 
00510 /// \brief access to the refCtr_ of an event \a e
00511 inline uint8_t QF_EVT_REF_CTR_(QEvt const * const e) { return e->refCtr_; }
00512 
00513 /// \brief increment the refCtr_ of an event \a e
00514 inline void QF_EVT_REF_CTR_INC_(QEvt const * const e) {
00515     ++(QF_EVT_CONST_CAST_(e))->refCtr_;
00516 }
00517 
00518 /// \brief decrement the refCtr_ of an event \a e
00519 inline void QF_EVT_REF_CTR_DEC_(QEvt const * const e) {
00520     --(QF_EVT_CONST_CAST_(e))->refCtr_;
00521 }
00522 
00523 //////////////////////////////////////////////////////////////////////////////
00524 // internal frequently used srongly-typed constants
00525 
00526 QTimeEvtCtr const tc_0 = static_cast<QTimeEvtCtr>(0);
00527 
00528 void     * const null_void = static_cast<void *>(0);
00529 QEvt const * const null_evt  = static_cast<QEvt const *>(0);
00530 QTimeEvt * const null_tevt = static_cast<QTimeEvt *>(0);
00531 QActive  * const null_act  = static_cast<QActive *>(0);
00532 
00533 QP_END_
00534 
00535 /// \brief access element at index \a i_ from the base pointer \a base_
00536 #define QF_PTR_AT_(base_, i_) (base_[i_])
00537 
00538 //////////////////////////////////////////////////////////////////////////////
00539 #ifdef Q_SPY                                   // QS software tracing enabled?
00540 
00541     #if (QF_EQUEUE_CTR_SIZE == 1)
00542 
00543         /// \brief Internal QS macro to output an unformatted event queue
00544         /// counter data element
00545         /// \note the counter size depends on the macro #QF_EQUEUE_CTR_SIZE.
00546         #define QS_EQC_(ctr_)       QS::u8_(ctr_)
00547     #elif (QF_EQUEUE_CTR_SIZE == 2)
00548         #define QS_EQC_(ctr_)       QS::u16_(ctr_)
00549     #elif (QF_EQUEUE_CTR_SIZE == 4)
00550         #define QS_EQC_(ctr_)       QS::u32_(ctr_)
00551     #else
00552         #error "QF_EQUEUE_CTR_SIZE not defined"
00553     #endif
00554 
00555 
00556     #if (QF_EVENT_SIZ_SIZE == 1)
00557 
00558         /// \brief Internal QS macro to output an unformatted event size
00559         /// data element
00560         /// \note the event size depends on the macro #QF_EVENT_SIZ_SIZE.
00561         #define QS_EVS_(size_)      QS::u8_(size_)
00562     #elif (QF_EVENT_SIZ_SIZE == 2)
00563         #define QS_EVS_(size_)      QS::u16_(size_)
00564     #elif (QF_EVENT_SIZ_SIZE == 4)
00565         #define QS_EVS_(size_)      QS::u32_(size_)
00566     #endif
00567 
00568 
00569     #if (QF_MPOOL_SIZ_SIZE == 1)
00570 
00571         /// \brief Internal QS macro to output an unformatted memory pool
00572         /// block-size data element
00573         /// \note the block-size depends on the macro #QF_MPOOL_SIZ_SIZE.
00574         #define QS_MPS_(size_)      QS::u8_(size_)
00575     #elif (QF_MPOOL_SIZ_SIZE == 2)
00576         #define QS_MPS_(size_)      QS::u16_(size_)
00577     #elif (QF_MPOOL_SIZ_SIZE == 4)
00578         #define QS_MPS_(size_)      QS::u32_(size_)
00579     #endif
00580 
00581     #if (QF_MPOOL_CTR_SIZE == 1)
00582 
00583         /// \brief Internal QS macro to output an unformatted memory pool
00584         /// block-counter data element
00585         /// \note the counter size depends on the macro #QF_MPOOL_CTR_SIZE.
00586         #define QS_MPC_(ctr_)       QS::u8_(ctr_)
00587     #elif (QF_MPOOL_CTR_SIZE == 2)
00588         #define QS_MPC_(ctr_)       QS::u16_(ctr_)
00589     #elif (QF_MPOOL_CTR_SIZE == 4)
00590         #define QS_MPC_(ctr_)       QS::u32_(ctr_)
00591     #endif
00592 
00593 
00594     #if (QF_TIMEEVT_CTR_SIZE == 1)
00595 
00596         /// \brief Internal QS macro to output an unformatted time event
00597         /// tick-counter data element
00598         /// \note the counter size depends on the macro #QF_TIMEEVT_CTR_SIZE.
00599         #define QS_TEC_(ctr_)       QS::u8_(ctr_)
00600     #elif (QF_TIMEEVT_CTR_SIZE == 2)
00601         #define QS_TEC_(ctr_)       QS::u16_(ctr_)
00602     #elif (QF_TIMEEVT_CTR_SIZE == 4)
00603         #define QS_TEC_(ctr_)       QS::u32_(ctr_)
00604     #endif
00605 
00606 #endif                                                                // Q_SPY
00607 
00608 // "qa_defer.cpp" ============================================================
00609 /// \brief QActive::defer() and QActive::recall() implementation.
00610 ///
00611 
00612 QP_BEGIN_
00613 
00614 //............................................................................
00615 void QActive::defer(QEQueue * const eq, QEvt const * const e) const {
00616     eq->postFIFO(e);
00617 }
00618 //............................................................................
00619 bool QActive::recall(QEQueue * const eq) {
00620     QEvt const * const e = eq->get();  // try to get evt from deferred queue
00621     bool const recalled = (e != null_evt);                 // event available?
00622     if (recalled) {
00623         postLIFO(e);      // post it to the front of the Active Object's queue
00624 
00625         QF_CRIT_STAT_
00626         QF_CRIT_ENTRY_();
00627 
00628         if (QF_EVT_POOL_ID_(e) != u8_0) {            // is it a dynamic event?
00629 
00630             // after posting to the AO's queue the event must be referenced
00631             // at least twice: once in the deferred event queue (eq->get()
00632             // did NOT decrement the reference counter) and once in the
00633             // AO's event queue.
00634             Q_ASSERT(QF_EVT_REF_CTR_(e) > u8_1);
00635 
00636             // we need to decrement the reference counter once, to account
00637             // for removing the event from the deferred event queue.
00638             //
00639             QF_EVT_REF_CTR_DEC_(e);         // decrement the reference counter
00640         }
00641 
00642         QF_CRIT_EXIT_();
00643     }
00644     return recalled;                                     // event not recalled
00645 }
00646 
00647 QP_END_
00648 
00649 
00650 // "qa_fifo.cpp" =============================================================
00651 /// \brief QActive::postFIFO() implementation.
00652 ///
00653 /// \note this source file is only included in the QF library when the native
00654 /// QF active object queue is used (instead of a message queue of an RTOS).
00655 
00656 QP_BEGIN_
00657 
00658 //............................................................................
00659 #ifndef Q_SPY
00660 void QActive::postFIFO(QEvt const * const e) {
00661 #else
00662 void QActive::postFIFO(QEvt const * const e, void const * const sender) {
00663 #endif
00664 
00665     QF_CRIT_STAT_
00666     QF_CRIT_ENTRY_();
00667 
00668     QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_FIFO, QS::aoObj_, this)
00669         QS_TIME_();                                               // timestamp
00670         QS_OBJ_(sender);                                  // the sender object
00671         QS_SIG_(e->sig);                            // the signal of the event
00672         QS_OBJ_(this);                                   // this active object
00673         QS_U8_(QF_EVT_POOL_ID_(e));                // the pool Id of the event
00674         QS_U8_(QF_EVT_REF_CTR_(e));              // the ref count of the event
00675         QS_EQC_(m_eQueue.m_nFree);                   // number of free entries
00676         QS_EQC_(m_eQueue.m_nMin);                // min number of free entries
00677     QS_END_NOCRIT_()
00678 
00679     if (QF_EVT_POOL_ID_(e) != u8_0) {                // is it a dynamic event?
00680         QF_EVT_REF_CTR_INC_(e);             // increment the reference counter
00681     }
00682 
00683     if (m_eQueue.m_frontEvt == null_evt) {              // is the queue empty?
00684         m_eQueue.m_frontEvt = e;                     // deliver event directly
00685         QACTIVE_EQUEUE_SIGNAL_(this);                // signal the event queue
00686     }
00687     else {               // queue is not empty, leave event in the ring-buffer
00688                                         // queue must accept all posted events
00689         Q_ASSERT(m_eQueue.m_nFree != static_cast<QEQueueCtr>(0));
00690                               // insert event pointer e into the buffer (FIFO)
00691         QF_PTR_AT_(m_eQueue.m_ring, m_eQueue.m_head) = e;
00692         if (m_eQueue.m_head == static_cast<QEQueueCtr>(0)) {  // need to wrap?
00693             m_eQueue.m_head = m_eQueue.m_end;                   // wrap around
00694         }
00695         --m_eQueue.m_head;
00696 
00697         --m_eQueue.m_nFree;                    // update number of free events
00698         if (m_eQueue.m_nMin > m_eQueue.m_nFree) {
00699             m_eQueue.m_nMin = m_eQueue.m_nFree;       // update minimum so far
00700         }
00701     }
00702     QF_CRIT_EXIT_();
00703 }
00704 
00705 QP_END_
00706 
00707 // "qa_get_.cpp" =============================================================
00708 /// \brief QActive::get_() and QF::getQueueMargin() definitions.
00709 ///
00710 /// \note this source file is only included in the QF library when the native
00711 /// QF active object queue is used (instead of a message queue of an RTOS).
00712 
00713 QP_BEGIN_
00714 
00715 //............................................................................
00716 QEvt const *QActive::get_(void) {
00717     QF_CRIT_STAT_
00718     QF_CRIT_ENTRY_();
00719 
00720     QACTIVE_EQUEUE_WAIT_(this);           // wait for event to arrive directly
00721 
00722     QEvt const *e = m_eQueue.m_frontEvt;
00723 
00724     if (m_eQueue.m_nFree != m_eQueue.m_end) { //any events in the ring buffer?
00725                                                  // remove event from the tail
00726         m_eQueue.m_frontEvt = QF_PTR_AT_(m_eQueue.m_ring, m_eQueue.m_tail);
00727         if (m_eQueue.m_tail == static_cast<QEQueueCtr>(0)) {  // need to wrap?
00728             m_eQueue.m_tail = m_eQueue.m_end;                   // wrap around
00729         }
00730         --m_eQueue.m_tail;
00731 
00732         ++m_eQueue.m_nFree;          // one more free event in the ring buffer
00733 
00734         QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_GET, QS::aoObj_, this)
00735             QS_TIME_();                                           // timestamp
00736             QS_SIG_(e->sig);                       // the signal of this event
00737             QS_OBJ_(this);                               // this active object
00738             QS_U8_(QF_EVT_POOL_ID_(e));            // the pool Id of the event
00739             QS_U8_(QF_EVT_REF_CTR_(e));          // the ref count of the event
00740             QS_EQC_(m_eQueue.m_nFree);               // number of free entries
00741         QS_END_NOCRIT_()
00742     }
00743     else {
00744         m_eQueue.m_frontEvt = null_evt;             // the queue becomes empty
00745         QACTIVE_EQUEUE_ONEMPTY_(this);
00746 
00747         QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_GET_LAST, QS::aoObj_, this)
00748             QS_TIME_();                                           // timestamp
00749             QS_SIG_(e->sig);                       // the signal of this event
00750             QS_OBJ_(this);                               // this active object
00751             QS_U8_(QF_EVT_POOL_ID_(e));            // the pool Id of the event
00752             QS_U8_(QF_EVT_REF_CTR_(e));          // the ref count of the event
00753         QS_END_NOCRIT_()
00754     }
00755     QF_CRIT_EXIT_();
00756     return e;
00757 }
00758 //............................................................................
00759 uint32_t QF::getQueueMargin(uint8_t const prio) {
00760     Q_REQUIRE((prio <= static_cast<uint8_t>(QF_MAX_ACTIVE))
00761               && (active_[prio] != static_cast<QActive *>(0)));
00762 
00763     QF_CRIT_STAT_
00764     QF_CRIT_ENTRY_();
00765     uint32_t margin = static_cast<uint32_t>(active_[prio]->m_eQueue.m_nMin);
00766     QF_CRIT_EXIT_();
00767 
00768     return margin;
00769 }
00770 
00771 QP_END_
00772 
00773 // "qa_lifo.cpp" =============================================================
00774 /// \brief QActive::postLIFO() implementation.
00775 ///
00776 /// \note this source file is only included in the QF library when the native
00777 /// QF active object queue is used (instead of a message queue of an RTOS).
00778 
00779 QP_BEGIN_
00780 
00781 //............................................................................
00782 void QActive::postLIFO(QEvt const * const e) {
00783     QF_CRIT_STAT_
00784     QF_CRIT_ENTRY_();
00785 
00786     QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_LIFO, QS::aoObj_, this)
00787         QS_TIME_();                                               // timestamp
00788         QS_SIG_(e->sig);                           // the signal of this event
00789         QS_OBJ_(this);                                   // this active object
00790         QS_U8_(QF_EVT_POOL_ID_(e));                // the pool Id of the event
00791         QS_U8_(QF_EVT_REF_CTR_(e));              // the ref count of the event
00792         QS_EQC_(m_eQueue.m_nFree);                   // number of free entries
00793         QS_EQC_(m_eQueue.m_nMin);                // min number of free entries
00794     QS_END_NOCRIT_()
00795 
00796     if (QF_EVT_POOL_ID_(e) != u8_0) {                // is it a dynamic event?
00797         QF_EVT_REF_CTR_INC_(e);             // increment the reference counter
00798     }
00799 
00800     if (m_eQueue.m_frontEvt == null_evt) {              // is the queue empty?
00801         m_eQueue.m_frontEvt = e;                     // deliver event directly
00802         QACTIVE_EQUEUE_SIGNAL_(this);                // signal the event queue
00803     }
00804     else {               // queue is not empty, leave event in the ring-buffer
00805                                         // queue must accept all posted events
00806         Q_ASSERT(m_eQueue.m_nFree != static_cast<QEQueueCtr>(0));
00807 
00808         ++m_eQueue.m_tail;
00809         if (m_eQueue.m_tail == m_eQueue.m_end) {     // need to wrap the tail?
00810             m_eQueue.m_tail = static_cast<QEQueueCtr>(0);       // wrap around
00811         }
00812 
00813         QF_PTR_AT_(m_eQueue.m_ring, m_eQueue.m_tail) = m_eQueue.m_frontEvt;
00814         m_eQueue.m_frontEvt = e;                         // put event to front
00815 
00816         --m_eQueue.m_nFree;                    // update number of free events
00817         if (m_eQueue.m_nMin > m_eQueue.m_nFree) {
00818             m_eQueue.m_nMin = m_eQueue.m_nFree;       // update minimum so far
00819         }
00820     }
00821     QF_CRIT_EXIT_();
00822 }
00823 
00824 QP_END_
00825 
00826 // "qa_sub.cpp" ==============================================================
00827 /// \brief QActive::subscribe() implementation.
00828 
00829 QP_BEGIN_
00830 
00831 //............................................................................
00832 void QActive::subscribe(enum_t const sig) const {
00833     uint8_t p = m_prio;
00834     Q_REQUIRE((Q_USER_SIG <= sig)
00835               && (sig < QF_maxSignal_)
00836               && (u8_0 < p) && (p <= static_cast<uint8_t>(QF_MAX_ACTIVE))
00837               && (QF::active_[p] == this));
00838 
00839     uint8_t const i = Q_ROM_BYTE(QF_div8Lkup[p]);
00840 
00841     QF_CRIT_STAT_
00842     QF_CRIT_ENTRY_();
00843 
00844     QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_SUBSCRIBE, QS::aoObj_, this)
00845         QS_TIME_();                                               // timestamp
00846         QS_SIG_(sig);                              // the signal of this event
00847         QS_OBJ_(this);                                   // this active object
00848     QS_END_NOCRIT_()
00849                                                        // set the priority bit
00850     QF_PTR_AT_(QF_subscrList_, sig).m_bits[i] |= Q_ROM_BYTE(QF_pwr2Lkup[p]);
00851     QF_CRIT_EXIT_();
00852 }
00853 
00854 QP_END_
00855 
00856 // "qa_usub.cpp" =============================================================
00857 /// \brief QActive::unsubscribe() implementation.
00858 
00859 QP_BEGIN_
00860 
00861 //............................................................................
00862 void QActive::unsubscribe(enum_t const sig) const {
00863     uint8_t p = m_prio;
00864     Q_REQUIRE((Q_USER_SIG <= sig)
00865               && (sig < QF_maxSignal_)
00866               && (u8_0 < p) && (p <= static_cast<uint8_t>(QF_MAX_ACTIVE))
00867               && (QF::active_[p] == this));
00868 
00869     uint8_t const i = Q_ROM_BYTE(QF_div8Lkup[p]);
00870 
00871     QF_CRIT_STAT_
00872     QF_CRIT_ENTRY_();
00873 
00874     QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_UNSUBSCRIBE, QS::aoObj_, this)
00875         QS_TIME_();                                               // timestamp
00876         QS_SIG_(sig);                              // the signal of this event
00877         QS_OBJ_(this);                                   // this active object
00878     QS_END_NOCRIT_()
00879                                                      // clear the priority bit
00880     QF_PTR_AT_(QF_subscrList_,sig).m_bits[i] &= Q_ROM_BYTE(QF_invPwr2Lkup[p]);
00881     QF_CRIT_EXIT_();
00882 }
00883 
00884 QP_END_
00885 
00886 // "qa_usuba.cpp" ============================================================
00887 /// \brief QActive::unsubscribeAll() implementation.
00888 
00889 QP_BEGIN_
00890 
00891 //............................................................................
00892 void QActive::unsubscribeAll(void) const {
00893     uint8_t const p = m_prio;
00894     Q_REQUIRE((u8_0 < p) && (p <= static_cast<uint8_t>(QF_MAX_ACTIVE))
00895               && (QF::active_[p] == this));
00896 
00897     uint8_t const i = Q_ROM_BYTE(QF_div8Lkup[p]);
00898 
00899     enum_t sig;
00900     for (sig = Q_USER_SIG; sig < QF_maxSignal_; ++sig) {
00901         QF_CRIT_STAT_
00902         QF_CRIT_ENTRY_();
00903         if ((QF_PTR_AT_(QF_subscrList_, sig).m_bits[i]
00904              & Q_ROM_BYTE(QF_pwr2Lkup[p])) != u8_0)
00905         {
00906 
00907             QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_UNSUBSCRIBE, QS::aoObj_, this)
00908                 QS_TIME_();                                       // timestamp
00909                 QS_SIG_(sig);                      // the signal of this event
00910                 QS_OBJ_(this);                           // this active object
00911             QS_END_NOCRIT_()
00912                                                      // clear the priority bit
00913             QF_PTR_AT_(QF_subscrList_, sig).m_bits[i] &=
00914                 Q_ROM_BYTE(QF_invPwr2Lkup[p]);
00915         }
00916         QF_CRIT_EXIT_();
00917     }
00918 }
00919 
00920 QP_END_
00921 
00922 // "qeq_fifo.cpp" ============================================================
00923 /// \brief QEQueue::postFIFO() implementation.
00924 
00925 QP_BEGIN_
00926 
00927 //............................................................................
00928 void QEQueue::postFIFO(QEvt const * const e) {
00929     QF_CRIT_STAT_
00930     QF_CRIT_ENTRY_();
00931 
00932     QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_POST_FIFO, QS::eqObj_, this)
00933         QS_TIME_();                                               // timestamp
00934         QS_SIG_(e->sig);                           // the signal of this event
00935         QS_OBJ_(this);                                    // this queue object
00936         QS_U8_(QF_EVT_POOL_ID_(e));                // the pool Id of the event
00937         QS_U8_(QF_EVT_REF_CTR_(e));              // the ref count of the event
00938         QS_EQC_(m_nFree);                            // number of free entries
00939         QS_EQC_(m_nMin);                         // min number of free entries
00940     QS_END_NOCRIT_()
00941 
00942     if (QF_EVT_POOL_ID_(e) != u8_0) {                // is it a dynamic event?
00943         QF_EVT_REF_CTR_INC_(e);             // increment the reference counter
00944     }
00945 
00946     if (m_frontEvt == null_evt) {                       // is the queue empty?
00947         m_frontEvt = e;                              // deliver event directly
00948     }
00949     else {               // queue is not empty, leave event in the ring-buffer
00950                // the queue must be able to accept the event (cannot overflow)
00951         Q_ASSERT(m_nFree != static_cast<QEQueueCtr>(0));
00952 
00953         QF_PTR_AT_(m_ring, m_head) = e; // insert event into the buffer (FIFO)
00954         if (m_head == static_cast<QEQueueCtr>(0)) {           // need to wrap?
00955             m_head = m_end;                                     // wrap around
00956         }
00957         --m_head;
00958 
00959         --m_nFree;                             // update number of free events
00960         if (m_nMin > m_nFree) {
00961             m_nMin = m_nFree;                         // update minimum so far
00962         }
00963     }
00964     QF_CRIT_EXIT_();
00965 }
00966 
00967 QP_END_
00968 
00969 // "qeq_get.cpp" =============================================================
00970 /// \brief QEQueue::get() implementation.
00971 
00972 QP_BEGIN_
00973 
00974 //............................................................................
00975 QEvt const *QEQueue::get(void) {
00976     QEvt const *e;
00977     QF_CRIT_STAT_
00978 
00979     QF_CRIT_ENTRY_();
00980     if (m_frontEvt == null_evt) {                       // is the queue empty?
00981         e = null_evt;                       // no event available at this time
00982     }
00983     else {
00984         e = m_frontEvt;
00985 
00986         if (m_nFree != m_end) {          // any events in the the ring buffer?
00987             m_frontEvt = QF_PTR_AT_(m_ring, m_tail);   // remove from the tail
00988             if (m_tail == static_cast<QEQueueCtr>(0)) {       // need to wrap?
00989                 m_tail = m_end;                                 // wrap around
00990             }
00991             --m_tail;
00992 
00993             ++m_nFree;               // one more free event in the ring buffer
00994 
00995             QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_GET, QS::eqObj_, this)
00996                 QS_TIME_();                                       // timestamp
00997                 QS_SIG_(e->sig);                   // the signal of this event
00998                 QS_OBJ_(this);                            // this queue object
00999                 QS_U8_(QF_EVT_POOL_ID_(e));        // the pool Id of the event
01000                 QS_U8_(QF_EVT_REF_CTR_(e));      // the ref count of the event
01001                 QS_EQC_(m_nFree);                    // number of free entries
01002             QS_END_NOCRIT_()
01003         }
01004         else {
01005             m_frontEvt = null_evt;                  // the queue becomes empty
01006 
01007             QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_GET_LAST, QS::eqObj_, this)
01008                 QS_TIME_();                                       // timestamp
01009                 QS_SIG_(e->sig);                   // the signal of this event
01010                 QS_OBJ_(this);                            // this queue object
01011                 QS_U8_(QF_EVT_POOL_ID_(e));        // the pool Id of the event
01012                 QS_U8_(QF_EVT_REF_CTR_(e));      // the ref count of the event
01013             QS_END_NOCRIT_()
01014         }
01015     }
01016     QF_CRIT_EXIT_();
01017     return e;
01018 }
01019 
01020 QP_END_
01021 
01022 // "qeq_init.cpp" ============================================================
01023 /// \brief QEQueue::init() implementation.
01024 
01025 QP_BEGIN_
01026 
01027 //............................................................................
01028 void QEQueue::init(QEvt const *qSto[], QEQueueCtr const qLen) {
01029     m_frontEvt = null_evt;                           // no events in the queue
01030     m_ring     = &qSto[0];
01031     m_end      = qLen;
01032     m_head     = static_cast<QEQueueCtr>(0);
01033     m_tail     = static_cast<QEQueueCtr>(0);
01034     m_nFree    = qLen;
01035     m_nMin     = qLen;
01036 
01037     QS_CRIT_STAT_
01038     QS_BEGIN_(QS_QF_EQUEUE_INIT, QS::eqObj_, this)
01039         QS_OBJ_(qSto);                                  // this QEQueue object
01040         QS_EQC_(qLen);                              // the length of the queue
01041     QS_END_()
01042 }
01043 
01044 QP_END_
01045 
01046 // "qeq_lifo.cpp" ============================================================
01047 /// \brief QEQueue::postLIFO() implementation.
01048 
01049 QP_BEGIN_
01050 
01051 //............................................................................
01052 void QEQueue::postLIFO(QEvt const * const e) {
01053     QF_CRIT_STAT_
01054     QF_CRIT_ENTRY_();
01055 
01056     QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_POST_LIFO, QS::eqObj_, this)
01057         QS_TIME_();                                               // timestamp
01058         QS_SIG_(e->sig);                           // the signal of this event
01059         QS_OBJ_(this);                                    // this queue object
01060         QS_U8_(QF_EVT_POOL_ID_(e));                // the pool Id of the event
01061         QS_U8_(QF_EVT_REF_CTR_(e));              // the ref count of the event
01062         QS_EQC_(m_nFree);                            // number of free entries
01063         QS_EQC_(m_nMin);                         // min number of free entries
01064     QS_END_NOCRIT_()
01065 
01066     if (QF_EVT_POOL_ID_(e) != u8_0) {                // is it a dynamic event?
01067         QF_EVT_REF_CTR_INC_(e);             // increment the reference counter
01068     }
01069 
01070     if (m_frontEvt != null_evt) {                   // is the queue not empty?
01071                // the queue must be able to accept the event (cannot overflow)
01072         Q_ASSERT(m_nFree != static_cast<QEQueueCtr>(0));
01073 
01074         ++m_tail;
01075         if (m_tail == m_end) {                       // need to wrap the tail?
01076             m_tail = static_cast<QEQueueCtr>(0);                // wrap around
01077         }
01078 
01079         QF_PTR_AT_(m_ring, m_tail) = m_frontEvt;   // buffer the old front evt
01080 
01081         --m_nFree;                             // update number of free events
01082         if (m_nMin > m_nFree) {
01083             m_nMin = m_nFree;                         // update minimum so far
01084         }
01085     }
01086 
01087     m_frontEvt = e;                        // stick the new event to the front
01088 
01089     QF_CRIT_EXIT_();
01090 }
01091 
01092 QP_END_
01093 
01094 // "qf_act.cpp" ==============================================================
01095 /// \brief QF::active_[], QF::getVersion(), and QF::add_()/QF::remove_()
01096 /// implementation.
01097 
01098 QP_BEGIN_
01099 
01100 // public objects ------------------------------------------------------------
01101 QActive *QF::active_[QF_MAX_ACTIVE + 1];        // to be used by QF ports only
01102 uint8_t QF_intLockNest_;                       // interrupt-lock nesting level
01103 
01104 //............................................................................
01105 char_t const Q_ROM * Q_ROM_VAR QF::getVersion(void) {
01106     uint8_t const u8_zero = static_cast<uint8_t>('0');
01107     static char_t const Q_ROM Q_ROM_VAR version[] = {
01108         static_cast<char_t>(((QP_VERSION >> 12) & 0xFU) + u8_zero),
01109         static_cast<char_t>('.'),
01110         static_cast<char_t>(((QP_VERSION >>  8) & 0xFU) + u8_zero),
01111         static_cast<char_t>('.'),
01112         static_cast<char_t>(((QP_VERSION >>  4) & 0xFU) + u8_zero),
01113         static_cast<char_t>((QP_VERSION         & 0xFU) + u8_zero),
01114         static_cast<char_t>('\0')
01115     };
01116     return version;
01117 }
01118 //............................................................................
01119 void QF::add_(QActive * const a) {
01120     uint8_t p = a->m_prio;
01121 
01122     Q_REQUIRE((u8_0 < p) && (p <= static_cast<uint8_t>(QF_MAX_ACTIVE))
01123               && (active_[p] == static_cast<QActive *>(0)));
01124 
01125     QF_CRIT_STAT_
01126     QF_CRIT_ENTRY_();
01127 
01128     active_[p] = a;            // registger the active object at this priority
01129 
01130     QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_ADD, QS::aoObj_, a)
01131         QS_TIME_();                                               // timestamp
01132         QS_OBJ_(a);                                       // the active object
01133         QS_U8_(p);                        // the priority of the active object
01134     QS_END_NOCRIT_()
01135 
01136     QF_CRIT_EXIT_();
01137 }
01138 //............................................................................
01139 void QF::remove_(QActive const * const a) {
01140     uint8_t p = a->m_prio;
01141 
01142     Q_REQUIRE((u8_0 < p) && (p <= static_cast<uint8_t>(QF_MAX_ACTIVE))
01143               && (active_[p] == a));
01144 
01145     QF_CRIT_STAT_
01146     QF_CRIT_ENTRY_();
01147 
01148     active_[p] = static_cast<QActive *>(0);      // free-up the priority level
01149 
01150     QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_REMOVE, QS::aoObj_, a)
01151         QS_TIME_();                                               // timestamp
01152         QS_OBJ_(a);                                       // the active object
01153         QS_U8_(p);                        // the priority of the active object
01154     QS_END_NOCRIT_()
01155 
01156     QF_CRIT_EXIT_();
01157 }
01158 
01159 QP_END_
01160 
01161 
01162 // "qf_gc.cpp" ===============================================================
01163 /// \brief QF::gc() implementation.
01164 
01165 QP_BEGIN_
01166 
01167 //............................................................................
01168 void QF::gc(QEvt const * const e) {
01169     if (QF_EVT_POOL_ID_(e) != u8_0) {                // is it a dynamic event?
01170         QF_CRIT_STAT_
01171         QF_CRIT_ENTRY_();
01172 
01173         if (QF_EVT_REF_CTR_(e) > u8_1) {     // isn't this the last reference?
01174             QF_EVT_REF_CTR_DEC_(e);               // decrement the ref counter
01175 
01176             QS_BEGIN_NOCRIT_(QS_QF_GC_ATTEMPT, null_void, null_void)
01177                 QS_TIME_();                                       // timestamp
01178                 QS_SIG_(e->sig);                    // the signal of the event
01179                 QS_U8_(QF_EVT_POOL_ID_(e));        // the pool Id of the event
01180                 QS_U8_(QF_EVT_REF_CTR_(e));      // the ref count of the event
01181             QS_END_NOCRIT_()
01182 
01183             QF_CRIT_EXIT_();
01184         }
01185         else {         // this is the last reference to this event, recycle it
01186             uint8_t idx = static_cast<uint8_t>(QF_EVT_POOL_ID_(e) - u8_1);
01187 
01188             QS_BEGIN_NOCRIT_(QS_QF_GC, null_void, null_void)
01189                 QS_TIME_();                                       // timestamp
01190                 QS_SIG_(e->sig);                    // the signal of the event
01191                 QS_U8_(QF_EVT_POOL_ID_(e));        // the pool Id of the event
01192                 QS_U8_(QF_EVT_REF_CTR_(e));      // the ref count of the event
01193             QS_END_NOCRIT_()
01194 
01195             QF_CRIT_EXIT_();
01196 
01197             Q_ASSERT(idx < QF_maxPool_);
01198 
01199 #ifdef Q_EVT_VIRTUAL
01200             QF_EVT_CONST_CAST_(e)->~QEvt();        // xtor, cast 'const' away,
01201                              // which is legitimate, because it's a pool event
01202 #endif
01203                   // cast 'const' away, which is OK, because it's a pool event
01204             QF_EPOOL_PUT_(QF_pool_[idx], QF_EVT_CONST_CAST_(e));
01205         }
01206     }
01207 }
01208 
01209 QP_END_
01210 
01211 // "qf_log2.cpp" =============================================================
01212 /// \brief QF_log2Lkup[] implementation.
01213 
01214 QP_BEGIN_
01215 
01216 // Global objects ------------------------------------------------------------
01217 uint8_t const Q_ROM Q_ROM_VAR QF_log2Lkup[256] = {
01218     static_cast<uint8_t>(0),
01219     static_cast<uint8_t>(1),
01220     static_cast<uint8_t>(2), static_cast<uint8_t>(2),
01221     static_cast<uint8_t>(3), static_cast<uint8_t>(3), static_cast<uint8_t>(3),
01222     static_cast<uint8_t>(3),
01223     static_cast<uint8_t>(4), static_cast<uint8_t>(4), static_cast<uint8_t>(4),
01224     static_cast<uint8_t>(4), static_cast<uint8_t>(4), static_cast<uint8_t>(4),
01225     static_cast<uint8_t>(4), static_cast<uint8_t>(4),
01226     static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
01227     static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
01228     static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
01229     static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
01230     static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
01231     static_cast<uint8_t>(5),
01232     static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
01233     static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
01234     static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
01235     static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
01236     static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
01237     static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
01238     static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
01239     static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
01240     static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
01241     static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
01242     static_cast<uint8_t>(6), static_cast<uint8_t>(6),
01243     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01244     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01245     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01246     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01247     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01248     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01249     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01250     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01251     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01252     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01253     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01254     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01255     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01256     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01257     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01258     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01259     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01260     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01261     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01262     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01263     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01264     static_cast<uint8_t>(7),
01265     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01266     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01267     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01268     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01269     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01270     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01271     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01272     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01273     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01274     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01275     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01276     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01277     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01278     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01279     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01280     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01281     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01282     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01283     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01284     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01285     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01286     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01287     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01288     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01289     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01290     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01291     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01292     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01293     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01294     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01295     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01296     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01297     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01298     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01299     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01300     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01301     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01302     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01303     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01304     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01305     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01306     static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
01307     static_cast<uint8_t>(8), static_cast<uint8_t>(8)
01308 };
01309 
01310 QP_END_
01311 
01312 // "qf_new.cpp" ==============================================================
01313 /// \brief QF::new_() implementation.
01314 
01315 QP_BEGIN_
01316 
01317 //............................................................................
01318 QEvt *QF::new_(QEvtSize const evtSize, enum_t const sig) {
01319                     // find the pool id that fits the requested event size ...
01320     uint8_t idx = u8_0;
01321     while (evtSize
01322            > static_cast<QEvtSize>(QF_EPOOL_EVENT_SIZE_(QF_pool_[idx])))
01323     {
01324         ++idx;
01325         Q_ASSERT(idx < QF_maxPool_);     // cannot run out of registered pools
01326     }
01327 
01328     QS_CRIT_STAT_
01329     QS_BEGIN_(QS_QF_NEW, null_void, null_void)
01330         QS_TIME_();                                               // timestamp
01331         QS_EVS_(evtSize);                             // the size of the event
01332         QS_SIG_(static_cast<QSignal>(sig));         // the signal of the event
01333     QS_END_()
01334 
01335     QEvt *e;
01336     QF_EPOOL_GET_(QF_pool_[idx], e);
01337     Q_ASSERT(e != static_cast<QEvt *>(0));// pool must not run out of events
01338 
01339     e->sig     = static_cast<QSignal>(sig);       // set signal for this event
01340     e->poolId_ = static_cast<uint8_t>(idx + u8_1); // store pool ID in the evt
01341     e->refCtr_ = u8_0;                       // set the reference counter to 0
01342 
01343     return e;
01344 }
01345 
01346 QP_END_
01347 
01348 // "qf_pool.cpp" =============================================================
01349 /// \brief QF_pool_[] and QF_maxPool_ definition, QF::poolInit()
01350 /// implementation.
01351 
01352 QP_BEGIN_
01353 
01354 // Package-scope objects -----------------------------------------------------
01355 QF_EPOOL_TYPE_ QF_pool_[QF_MAX_EPOOL];             // allocate the event pools
01356 uint8_t QF_maxPool_;                      // number of initialized event pools
01357 
01358 //............................................................................
01359 void QF::poolInit(void * const poolSto,
01360                   uint32_t const poolSize, uint32_t const evtSize)
01361 {
01362                          // cannot exceed the number of available memory pools
01363     Q_REQUIRE(QF_maxPool_ < static_cast<uint8_t>(Q_DIM(QF_pool_)));
01364                // please initialize event pools in ascending order of evtSize:
01365     Q_REQUIRE((QF_maxPool_ == u8_0)
01366               || (QF_EPOOL_EVENT_SIZE_(QF_pool_[QF_maxPool_ - u8_1])
01367                   < evtSize));
01368     QF_EPOOL_INIT_(QF_pool_[QF_maxPool_], poolSto, poolSize, evtSize);
01369     ++QF_maxPool_;                                            // one more pool
01370 }
01371 
01372 QP_END_
01373 
01374 
01375 // "qf_psini.cpp" ============================================================
01376 /// \brief QF_subscrList_ and QF_maxSignal_ definition, QF::psInit()
01377 /// implementation.
01378 
01379 QP_BEGIN_
01380 
01381 // Package-scope objects -----------------------------------------------------
01382 QSubscrList *QF_subscrList_;
01383 enum_t QF_maxSignal_;
01384 
01385 //............................................................................
01386 void QF::psInit(QSubscrList * const subscrSto, uint32_t const maxSignal) {
01387     QF_subscrList_ = subscrSto;
01388     QF_maxSignal_  = static_cast<enum_t>(maxSignal);
01389 }
01390 
01391 QP_END_
01392 
01393 // "qf_pspub.cpp" ============================================================
01394 /// \brief QF::publish() implementation.
01395 
01396 QP_BEGIN_
01397 
01398 //............................................................................
01399 #ifndef Q_SPY
01400 void QF::publish(QEvt const * const e) {
01401 #else
01402 void QF::publish(QEvt const * const e, void const * const sender) {
01403 #endif
01404          // make sure that the published signal is within the configured range
01405     Q_REQUIRE(static_cast<enum_t>(e->sig) < QF_maxSignal_);
01406 
01407     QF_CRIT_STAT_
01408     QF_CRIT_ENTRY_();
01409 
01410     QS_BEGIN_NOCRIT_(QS_QF_PUBLISH, null_void, null_void)
01411         QS_TIME_();                                           // the timestamp
01412         QS_OBJ_(sender);                                  // the sender object
01413         QS_SIG_(e->sig);                            // the signal of the event
01414         QS_U8_(QF_EVT_POOL_ID_(e));                // the pool Id of the event
01415         QS_U8_(QF_EVT_REF_CTR_(e));              // the ref count of the event
01416     QS_END_NOCRIT_()
01417 
01418     if (QF_EVT_POOL_ID_(e) != u8_0) {                // is it a dynamic event?
01419         QF_EVT_REF_CTR_INC_(e);     // increment the reference counter, NOTE01
01420     }
01421     QF_CRIT_EXIT_();
01422 
01423 #if (QF_MAX_ACTIVE <= 8)
01424     uint8_t tmp = QF_PTR_AT_(QF_subscrList_, e->sig).m_bits[0];
01425     while (tmp != u8_0) {
01426         uint8_t p = Q_ROM_BYTE(QF_log2Lkup[tmp]);
01427         tmp &= Q_ROM_BYTE(QF_invPwr2Lkup[p]);      // clear the subscriber bit
01428         Q_ASSERT(active_[p] != static_cast<QActive *>(0));//must be registered
01429 
01430                            // POST() asserts internally if the queue overflows
01431         active_[p]->POST(e, sender);
01432     }
01433 #else
01434                                                 // number of bytes in the list
01435     uint8_t i = QF_SUBSCR_LIST_SIZE;
01436     do {                       // go through all bytes in the subsciption list
01437         --i;
01438         uint8_t tmp = QF_PTR_AT_(QF_subscrList_, e->sig).m_bits[i];
01439         while (tmp != u8_0) {
01440             uint8_t p = Q_ROM_BYTE(QF_log2Lkup[tmp]);
01441             tmp &= Q_ROM_BYTE(QF_invPwr2Lkup[p]);  // clear the subscriber bit
01442                                                         // adjust the priority
01443             p = static_cast<uint8_t>(p + static_cast<uint8_t>(i << 3));
01444             Q_ASSERT(active_[p] != static_cast<QActive *>(0));   // registered
01445 
01446                            // POST() asserts internally if the queue overflows
01447             active_[p]->POST(e, sender);
01448         }
01449     } while (i != u8_0);
01450 #endif
01451 
01452     gc(e);                            // run the garbage collector, see NOTE01
01453 }
01454 
01455 QP_END_
01456 
01457 
01458 // "qf_pwr2.cpp" =============================================================
01459 /// \brief QF_pwr2Lkup[], QF_invPwr2Lkup[], and QF_div8Lkup[] definitions.
01460 
01461 QP_BEGIN_
01462 
01463 // Global objects ------------------------------------------------------------
01464 uint8_t const Q_ROM Q_ROM_VAR QF_pwr2Lkup[65] = {
01465     static_cast<uint8_t>(0x00),                             // unused location
01466     static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
01467     static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
01468     static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
01469     static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
01470     static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
01471     static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
01472     static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
01473     static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
01474     static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
01475     static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
01476     static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
01477     static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
01478     static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
01479     static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
01480     static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
01481     static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
01482     static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
01483     static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
01484     static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
01485     static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
01486     static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
01487     static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
01488     static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
01489     static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
01490     static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
01491     static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
01492     static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
01493     static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
01494     static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
01495     static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
01496     static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
01497     static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80)
01498 };
01499 
01500 uint8_t const Q_ROM Q_ROM_VAR QF_invPwr2Lkup[65] = {
01501     static_cast<uint8_t>(0xFF),                             // unused location
01502     static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
01503     static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
01504     static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
01505     static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
01506     static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
01507     static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
01508     static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
01509     static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
01510     static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
01511     static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
01512     static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
01513     static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
01514     static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
01515     static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
01516     static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
01517     static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
01518     static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
01519     static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
01520     static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
01521     static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
01522     static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
01523     static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
01524     static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
01525     static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
01526     static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
01527     static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
01528     static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
01529     static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
01530     static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
01531     static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
01532     static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
01533     static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F)
01534 };
01535 
01536 uint8_t const Q_ROM Q_ROM_VAR QF_div8Lkup[65] = {
01537     static_cast<uint8_t>(0),                                // unused location
01538     static_cast<uint8_t>(0), static_cast<uint8_t>(0), static_cast<uint8_t>(0),
01539     static_cast<uint8_t>(0), static_cast<uint8_t>(0), static_cast<uint8_t>(0),
01540     static_cast<uint8_t>(0), static_cast<uint8_t>(0),
01541     static_cast<uint8_t>(1), static_cast<uint8_t>(1), static_cast<uint8_t>(1),
01542     static_cast<uint8_t>(1), static_cast<uint8_t>(1), static_cast<uint8_t>(1),
01543     static_cast<uint8_t>(1), static_cast<uint8_t>(1),
01544     static_cast<uint8_t>(2), static_cast<uint8_t>(2), static_cast<uint8_t>(2),
01545     static_cast<uint8_t>(2), static_cast<uint8_t>(2), static_cast<uint8_t>(2),
01546     static_cast<uint8_t>(2), static_cast<uint8_t>(2),
01547     static_cast<uint8_t>(3), static_cast<uint8_t>(3), static_cast<uint8_t>(3),
01548     static_cast<uint8_t>(3), static_cast<uint8_t>(3), static_cast<uint8_t>(3),
01549     static_cast<uint8_t>(3), static_cast<uint8_t>(3),
01550     static_cast<uint8_t>(4), static_cast<uint8_t>(4), static_cast<uint8_t>(4),
01551     static_cast<uint8_t>(4), static_cast<uint8_t>(4), static_cast<uint8_t>(4),
01552     static_cast<uint8_t>(4), static_cast<uint8_t>(4),
01553     static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
01554     static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
01555     static_cast<uint8_t>(5), static_cast<uint8_t>(5),
01556     static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
01557     static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
01558     static_cast<uint8_t>(6), static_cast<uint8_t>(6),
01559     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01560     static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
01561     static_cast<uint8_t>(7), static_cast<uint8_t>(7)
01562 };
01563 
01564 QP_END_
01565 
01566 // "qf_tick.cpp" =============================================================
01567 /// \brief QF::tick() implementation.
01568 
01569 QP_BEGIN_
01570 
01571 //............................................................................
01572 #ifndef Q_SPY
01573 void QF::tick(void) {                                            // see NOTE01
01574 #else
01575 void QF::tick(void const * const sender) {
01576 #endif
01577 
01578     QF_CRIT_STAT_
01579     QF_CRIT_ENTRY_();
01580 
01581     QS_BEGIN_NOCRIT_(QS_QF_TICK, null_void, null_void)
01582         QS_TEC_(static_cast<QTimeEvtCtr>(++QS::tickCtr_)); // the tick counter
01583     QS_END_NOCRIT_()
01584 
01585     QTimeEvt *prev = null_tevt;
01586     for (QTimeEvt *t = QF_timeEvtListHead_; t != null_tevt; t = t->m_next) {
01587         if (t->m_ctr == tc_0) {            // time evt. scheduled for removal?
01588             if (t == QF_timeEvtListHead_) {
01589                 QF_timeEvtListHead_ = t->m_next;
01590             }
01591             else {
01592                 Q_ASSERT(prev != null_tevt);
01593                 prev->m_next = t->m_next;
01594             }
01595             QF_EVT_REF_CTR_DEC_(t);                      // mark as not linked
01596         }
01597         else {
01598             --t->m_ctr;
01599             if (t->m_ctr == tc_0) {                        // about to expire?
01600                 if (t->m_interval != tc_0) {           // periodic time event?
01601                     t->m_ctr = t->m_interval;            // rearm the time evt
01602                 }
01603                 else {
01604                     QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_AUTO_DISARM, QS::teObj_, t)
01605                         QS_OBJ_(t);                  // this time event object
01606                         QS_OBJ_(t->m_act);                // the active object
01607                     QS_END_NOCRIT_()
01608                 }
01609 
01610                 QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_POST, QS::teObj_, t)
01611                     QS_TIME_();                                   // timestamp
01612                     QS_OBJ_(t);                       // the time event object
01613                     QS_SIG_(t->sig);          // the signal of this time event
01614                     QS_OBJ_(t->m_act);                    // the active object
01615                 QS_END_NOCRIT_()
01616 
01617                 QF_CRIT_EXIT_();         // leave crit. section before posting
01618                            // POST() asserts internally if the queue overflows
01619                 t->m_act->POST(t, sender);
01620                 QF_CRIT_ENTRY_();        // re-enter crit. section to continue
01621 
01622                 if (t->m_ctr == tc_0) {             // still marked to expire?
01623                     if (t == QF_timeEvtListHead_) {
01624                         QF_timeEvtListHead_ = t->m_next;
01625                     }
01626                     else {
01627                         Q_ASSERT(prev != null_tevt);
01628                         prev->m_next = t->m_next;
01629                     }
01630                     QF_EVT_REF_CTR_DEC_(t);                 // mark as removed
01631                 }
01632                 else {
01633                     prev = t;
01634                 }
01635             }
01636             else {
01637                 prev = t;
01638             }
01639         }
01640     }
01641     QF_CRIT_EXIT_();
01642 }
01643 
01644 QP_END_
01645 
01646 // "qmp_get.cpp" =============================================================
01647 /// \brief QMPool::get() and QF::getPoolMargin() implementation.
01648 
01649 QP_BEGIN_
01650 
01651 //............................................................................
01652 void *QMPool::get(void) {
01653     QF_CRIT_STAT_
01654     QF_CRIT_ENTRY_();
01655 
01656     QFreeBlock *fb = static_cast<QFreeBlock *>(m_free);  // free block or NULL
01657     if (fb != static_cast<QFreeBlock *>(0)) {         // free block available?
01658         m_free = fb->m_next;        // adjust list head to the next free block
01659 
01660         Q_ASSERT(m_nFree > static_cast<QMPoolCtr>(0));    // at least one free
01661         --m_nFree;                                      // one free block less
01662         if (m_nMin > m_nFree) {
01663             m_nMin = m_nFree;                   // remember the minimum so far
01664         }
01665     }
01666 
01667     QS_BEGIN_NOCRIT_(QS_QF_MPOOL_GET, QS::mpObj_, m_start)
01668         QS_TIME_();                                               // timestamp
01669         QS_OBJ_(m_start);                   // the memory managed by this pool
01670         QS_MPC_(m_nFree);             // the number of free blocks in the pool
01671         QS_MPC_(m_nMin);     // the mninimum number of free blocks in the pool
01672     QS_END_NOCRIT_()
01673 
01674     QF_CRIT_EXIT_();
01675     return fb;               // return the block or NULL pointer to the caller
01676 }
01677 //............................................................................
01678 uint32_t QF::getPoolMargin(uint8_t const poolId) {
01679     Q_REQUIRE((u8_1 <= poolId) && (poolId <= QF_maxPool_));
01680 
01681     QF_CRIT_STAT_
01682     QF_CRIT_ENTRY_();
01683     uint32_t margin = static_cast<uint32_t>(QF_pool_[poolId - u8_1].m_nMin);
01684     QF_CRIT_EXIT_();
01685 
01686     return margin;
01687 }
01688 
01689 QP_END_
01690 
01691 // "qmp_init.cpp" ============================================================
01692 /// \brief QMPool::init() implementation.
01693 
01694 QP_BEGIN_
01695 
01696 //............................................................................
01697 void QMPool::init(void * const poolSto, uint32_t const poolSize,
01698                   QMPoolSize const blockSize)
01699 {
01700     // The memory block must be valid
01701     // and the poolSize must fit at least one free block
01702     // and the blockSize must not be too close to the top of the dynamic range
01703     Q_REQUIRE((poolSto != null_void)
01704               && (poolSize >= static_cast<uint32_t>(sizeof(QFreeBlock)))
01705               && ((blockSize + static_cast<QMPoolSize>(sizeof(QFreeBlock)))
01706                     > blockSize));
01707 
01708     m_free = poolSto;
01709 
01710                 // round up the blockSize to fit an integer number of pointers
01711     m_blockSize = static_cast<QMPoolSize>(sizeof(QFreeBlock));//start with one
01712     uint32_t nblocks = static_cast<uint32_t>(1);//# free blocks in a mem block
01713     while (m_blockSize < blockSize) {
01714         m_blockSize += static_cast<QMPoolSize>(sizeof(QFreeBlock));
01715         ++nblocks;
01716     }
01717 
01718                // the whole pool buffer must fit at least one rounded-up block
01719     Q_ASSERT(poolSize >= static_cast<uint32_t>(m_blockSize));
01720 
01721                                 // chain all blocks together in a free-list...
01722                                                      // don't chain last block
01723     uint32_t availSize = poolSize - static_cast<uint32_t>(m_blockSize);
01724     m_nTot = static_cast<QMPoolCtr>(1);    // one (the last) block in the pool
01725                                           //start at the head of the free list
01726     QFreeBlock *fb = static_cast<QFreeBlock *>(m_free);
01727     while (availSize >= static_cast<uint32_t>(m_blockSize)) {
01728         fb->m_next = &QF_PTR_AT_(fb, nblocks);          // setup the next link
01729         fb = fb->m_next;                              // advance to next block
01730         availSize -= static_cast<uint32_t>(m_blockSize);// less available size
01731         ++m_nTot;                     // increment the number of blocks so far
01732     }
01733 
01734     fb->m_next = static_cast<QFreeBlock *>(0); // the last link points to NULL
01735     m_nFree    = m_nTot;                                // all blocks are free
01736     m_nMin     = m_nTot;                  // the minimum number of free blocks
01737     m_start    = poolSto;               // the original start this pool buffer
01738     m_end      = fb;                            // the last block in this pool
01739 
01740     QS_CRIT_STAT_
01741     QS_BEGIN_(QS_QF_MPOOL_INIT, QS::mpObj_, m_start)
01742         QS_OBJ_(m_start);                   // the memory managed by this pool
01743         QS_MPC_(m_nTot);                         // the total number of blocks
01744     QS_END_()
01745 }
01746 
01747 QP_END_
01748 
01749 // "qmp_put.cpp" =============================================================
01750 /// \brief QMPool::put() implementation.
01751 
01752 QP_BEGIN_
01753 
01754 // This macro is specifically and exclusively used for checking the range
01755 // of a block pointer returned to the pool. Such a check must rely on the
01756 // pointer arithmetic not compliant with the MISRA-C++:2008 rules ??? and
01757 // ???. Defining a specific macro for this purpose allows to selectively
01758 // disable the warnings for this particular case.
01759 //
01760 #define QF_PTR_RANGE_(x_, min_, max_)  (((min_) <= (x_)) && ((x_) <= (max_)))
01761 
01762 //............................................................................
01763 void QMPool::put(void * const b) {
01764 
01765     Q_REQUIRE(m_nFree < m_nTot);         // adding one free so, # free < total
01766     Q_REQUIRE(QF_PTR_RANGE_(b, m_start, m_end));         // b must be in range
01767 
01768     QF_CRIT_STAT_
01769     QF_CRIT_ENTRY_();
01770 
01771                                                     // link into the free list
01772     (static_cast<QFreeBlock*>(b))->m_next = static_cast<QFreeBlock *>(m_free);
01773     m_free = b;                            // set as new head of the free list
01774     ++m_nFree;                             // one more free block in this pool
01775 
01776     QS_BEGIN_NOCRIT_(QS_QF_MPOOL_PUT, QS::mpObj_, m_start)
01777         QS_TIME_();                                               // timestamp
01778         QS_OBJ_(m_start);                   // the memory managed by this pool
01779         QS_MPC_(m_nFree);             // the number of free blocks in the pool
01780     QS_END_NOCRIT_()
01781 
01782     QF_CRIT_EXIT_();
01783 }
01784 
01785 QP_END_
01786 
01787 
01788 // "qte_arm.cpp" =============================================================
01789 /// \brief QF_timeEvtListHead_ definition and QTimeEvt::arm_() implementation.
01790 
01791 QP_BEGIN_
01792 
01793 // Package-scope objects -----------------------------------------------------
01794 QTimeEvt *QF_timeEvtListHead_;           // head of linked list of time events
01795 
01796 //............................................................................
01797 bool QF::noTimeEvtsActive(void) {
01798     return QF_timeEvtListHead_ == null_tevt;
01799 }
01800 //............................................................................
01801 void QTimeEvt::arm_(QActive * const act, QTimeEvtCtr const nTicks) {
01802     Q_REQUIRE((nTicks > tc_0)                    /* cannot arm with 0 ticks */
01803               && (act != null_act)        /* Active object must be provided */
01804               && (m_ctr == tc_0)                        /* must be disarmed */
01805               && (static_cast<enum_t>(sig) >= Q_USER_SIG));    // valid signal
01806     QF_CRIT_STAT_
01807     QF_CRIT_ENTRY_();
01808     m_ctr  = nTicks;
01809     m_act  = act;
01810     if (refCtr_ == u8_0) {                                      // not linked?
01811         m_next = QF_timeEvtListHead_;
01812         QF_timeEvtListHead_ = this;
01813         QF_EVT_REF_CTR_INC_(this);                           // mark as linked
01814     }
01815 
01816     QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_ARM, QS::teObj_, this)
01817         QS_TIME_();                                               // timestamp
01818         QS_OBJ_(this);                               // this time event object
01819         QS_OBJ_(act);                                     // the active object
01820         QS_TEC_(nTicks);                                // the number of ticks
01821         QS_TEC_(m_interval);                                   // the interval
01822     QS_END_NOCRIT_()
01823 
01824     QF_CRIT_EXIT_();
01825 }
01826 
01827 QP_END_
01828 
01829 
01830 // "qte_ctor.cpp" ============================================================
01831 /// \brief QTimeEvt::QTimeEvt() implementation.
01832 QP_BEGIN_
01833 
01834 //............................................................................
01835 QTimeEvt::QTimeEvt(enum_t const s)
01836   :
01837 #ifdef Q_EVT_CTOR
01838     QEvt(static_cast<QSignal>(s)),
01839 #endif
01840     m_next(null_tevt),
01841     m_act(null_act),
01842     m_ctr(tc_0),
01843     m_interval(tc_0)
01844 {
01845     Q_REQUIRE(s >= Q_USER_SIG);                        // signal must be valid
01846 #ifndef Q_EVT_CTOR
01847     sig = static_cast<QSignal>(s);
01848 #endif
01849                                       // time event must be static, see NOTE01
01850     poolId_ = u8_0;                                 // not from any event pool
01851     refCtr_ = u8_0;                                              // not linked
01852 }
01853 
01854 QP_END_
01855 
01856 
01857 // "qte_ctr.cpp" =============================================================
01858 /// \brief QTimeEvt::ctr() implementation.
01859 
01860 QP_BEGIN_
01861 
01862 //............................................................................
01863 QTimeEvtCtr QTimeEvt::ctr(void) const {
01864     QF_CRIT_STAT_
01865 
01866     QF_CRIT_ENTRY_();
01867     QTimeEvtCtr ret = m_ctr;
01868 
01869     QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_CTR, QS::teObj_, this)
01870         QS_TIME_();                                               // timestamp
01871         QS_OBJ_(this);                               // this time event object
01872         QS_OBJ_(m_act);                                   // the active object
01873         QS_TEC_(ret);                                   // the current counter
01874         QS_TEC_(m_interval);                                   // the interval
01875     QS_END_NOCRIT_()
01876 
01877     QF_CRIT_EXIT_();
01878     return ret;
01879 }
01880 
01881 QP_END_
01882 
01883 // "qte_darm.cpp" ============================================================
01884 /// \brief QTimeEvt::disarm() implementation.
01885 
01886 QP_BEGIN_
01887 
01888 //............................................................................
01889 // NOTE: disarm a time evt (no harm in disarming an already disarmed time evt)
01890 bool QTimeEvt::disarm(void) {
01891     QF_CRIT_STAT_
01892     QF_CRIT_ENTRY_();
01893     bool wasArmed;
01894     if (m_ctr != tc_0) {                  // is the time event actually armed?
01895         wasArmed = true;
01896 
01897         QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_DISARM, QS::teObj_, this)
01898             QS_TIME_();                                           // timestamp
01899             QS_OBJ_(this);                           // this time event object
01900             QS_OBJ_(m_act);                               // the active object
01901             QS_TEC_(m_ctr);                             // the number of ticks
01902             QS_TEC_(m_interval);                               // the interval
01903         QS_END_NOCRIT_()
01904 
01905         m_ctr = tc_0;                        // schedule removal from the list
01906     }
01907     else {                                     // the time event was not armed
01908         wasArmed = false;
01909 
01910         QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_DISARM_ATTEMPT, QS::teObj_, this)
01911             QS_TIME_();                                           // timestamp
01912             QS_OBJ_(this);                           // this time event object
01913             QS_OBJ_(m_act);                               // the active object
01914         QS_END_NOCRIT_()
01915     }
01916     QF_CRIT_EXIT_();
01917     return wasArmed;
01918 }
01919 
01920 QP_END_
01921 
01922 
01923 // "qte_rarm.cpp" ============================================================
01924 /// \brief QTimeEvt::rearm() implementation.
01925 
01926 QP_BEGIN_
01927 
01928 //............................................................................
01929 bool QTimeEvt::rearm(QTimeEvtCtr const nTicks) {
01930     Q_REQUIRE((nTicks > tc_0)                  /* cannot rearm with 0 ticks */
01931               && (m_act != null_act)         /* active object must be valid */
01932               && (static_cast<enum_t>(sig) >= Q_USER_SIG));    // valid signal
01933 
01934     QF_CRIT_STAT_
01935     QF_CRIT_ENTRY_();
01936 
01937     bool isArmed;
01938     if (m_ctr == tc_0) {                       // is this time event disarmed?
01939         isArmed = false;
01940         m_next = QF_timeEvtListHead_;
01941         if (QF_timeEvtListHead_ != null_tevt) {
01942             m_next = QF_timeEvtListHead_;
01943             QF_timeEvtListHead_ = this;
01944             QF_EVT_REF_CTR_INC_(this);                       // mark as linked
01945         }
01946     }
01947     else {
01948         isArmed = true;
01949     }
01950     m_ctr = nTicks;            // re-load the tick counter (shift the phasing)
01951 
01952     QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_REARM, QS::teObj_, this)
01953         QS_TIME_();                                               // timestamp
01954         QS_OBJ_(this);                               // this time event object
01955         QS_OBJ_(m_act);                                   // the active object
01956         QS_TEC_(m_ctr);                                 // the number of ticks
01957         QS_TEC_(m_interval);                                   // the interval
01958         QS_U8_(isArmed ? u8_1 : u8_0);                 // was the timer armed?
01959     QS_END_NOCRIT_()
01960 
01961     QF_CRIT_EXIT_();
01962     return isArmed;
01963 }
01964 
01965 QP_END_
01966 
01967 
01968 //////////////////////////////////////////////////////////////////////////////
01969 // Kernel selection based on QK_PREEMPTIVE
01970 //
01971 #ifdef QK_PREEMPTIVE
01972 
01973 // "qk_pkg.h" ================================================================
01974 /// \brief Internal (package scope) QK/C interface.
01975 
01976 #ifndef QF_CRIT_STAT_TYPE
01977     /// \brief This is an internal macro for defining the critical section
01978     /// status type.
01979     ///
01980     /// The purpose of this macro is to enable writing the same code for the
01981     /// case when critical sectgion status type is defined and when it is not.
01982     /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
01983     /// provides the definition of the critical section status varaible.
01984     /// Otherwise this macro is empty.
01985     /// \sa #QF_CRIT_STAT_TYPE
01986     #define QF_CRIT_STAT_
01987 
01988     /// \brief This is an internal macro for entering a critical section.
01989     ///
01990     /// The purpose of this macro is to enable writing the same code for the
01991     /// case when critical sectgion status type is defined and when it is not.
01992     /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
01993     /// invokes #QF_CRIT_ENTRY passing the key variable as the parameter.
01994     /// Otherwise #QF_CRIT_ENTRY is invoked with a dummy parameter.
01995     /// \sa #QF_CRIT_ENTRY
01996     #define QF_CRIT_ENTRY_()    QF_CRIT_ENTRY(dummy)
01997 
01998     /// \brief This is an internal macro for exiting a cricial section.
01999     ///
02000     /// The purpose of this macro is to enable writing the same code for the
02001     /// case when critical sectgion status type is defined and when it is not.
02002     /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
02003     /// invokes #QF_CRIT_EXIT passing the key variable as the parameter.
02004     /// Otherwise #QF_CRIT_EXIT is invoked with a dummy parameter.
02005     /// \sa #QF_CRIT_EXIT
02006     #define QF_CRIT_EXIT_()     QF_CRIT_EXIT(dummy)
02007 
02008 #else
02009     #define QF_CRIT_STAT_       QF_CRIT_STAT_TYPE critStat_;
02010     #define QF_CRIT_ENTRY_()    QF_CRIT_ENTRY(critStat_)
02011     #define QF_CRIT_EXIT_()     QF_CRIT_EXIT(critStat_)
02012 #endif
02013                              // define for backwards compatibility, see NOTE01
02014 #ifndef QF_CRIT_STAT_TYPE
02015 #if !defined(QF_INT_DISABLE) && defined(QF_CRIT_ENTRY)
02016     #define QF_INT_DISABLE()    QF_CRIT_ENTRY(dummy)
02017 #endif
02018 #if !defined(QF_INT_ENABLE) && defined(QF_CRIT_EXIT)
02019     #define QF_INT_ENABLE()     QF_CRIT_EXIT(dummy)
02020 #endif
02021 #endif                                                    // QF_CRIT_STAT_TYPE
02022 
02023                                                    // package-scope objects...
02024 #ifndef QK_NO_MUTEX
02025     extern "C" uint8_t QK_ceilingPrio_;         ///< QK mutex priority ceiling
02026 #endif
02027 
02028 // "qk.cpp" ==================================================================
02029 /// \brief QK_readySet_, QK_currPrio_, and QK_intNest_ definitions and
02030 /// QK::getVersion(), QF::init(), QF::run(), QF::stop(),
02031 /// QActive::start(), QActive::stop() implementations.
02032 
02033 // Public-scope objects ------------------------------------------------------
02034 extern "C" {
02035 #if (QF_MAX_ACTIVE <= 8)
02036     QP_ QPSet8  QK_readySet_;                               // ready set of QK
02037 #else
02038     QP_ QPSet64 QK_readySet_;                               // ready set of QK
02039 #endif
02040                                          // start with the QK scheduler locked
02041 uint8_t QK_currPrio_ = static_cast<uint8_t>(QF_MAX_ACTIVE + 1);
02042 uint8_t QK_intNest_;                          // start with nesting level of 0
02043 
02044 }                                                                // extern "C"
02045 
02046 QP_BEGIN_
02047 
02048 //............................................................................
02049 char_t const Q_ROM * Q_ROM_VAR QK::getVersion(void) {
02050     uint8_t const u8_zero = static_cast<uint8_t>('0');
02051     static char_t const Q_ROM Q_ROM_VAR version[] = {
02052         static_cast<char_t>(((QP_VERSION >> 12) & 0xFU) + u8_zero),
02053         static_cast<char_t>('.'),
02054         static_cast<char_t>(((QP_VERSION >>  8) & 0xFU) + u8_zero),
02055         static_cast<char_t>('.'),
02056         static_cast<char_t>(((QP_VERSION >>  4) & 0xFU) + u8_zero),
02057         static_cast<char_t>((QP_VERSION         & 0xFU) + u8_zero),
02058         static_cast<char_t>('\0')
02059     };
02060     return version;
02061 }
02062 //............................................................................
02063 void QF::init(void) {
02064     QK_init();           // QK initialization ("C" linkage, might be assembly)
02065 }
02066 //............................................................................
02067 void QF::stop(void) {
02068     QF::onCleanup();                                       // cleanup callback
02069     // nothing else to do for the QK preemptive kernel
02070 }
02071 //............................................................................
02072 static void initialize(void) {
02073     QK_currPrio_ = static_cast<uint8_t>(0);   // priority for the QK idle loop
02074     uint8_t p = QK_schedPrio_();
02075     if (p != static_cast<uint8_t>(0)) {
02076         QK_sched_(p);                    // process all events produced so far
02077     }
02078 }
02079 //............................................................................
02080 int16_t QF::run(void) {
02081     QF_INT_DISABLE();
02082     initialize();
02083     onStartup();                                           // startup callback
02084     QF_INT_ENABLE();
02085 
02086     for (;;) {                                             // the QK idle loop
02087         QK::onIdle();                        // invoke the QK on-idle callback
02088     }
02089                       // this unreachable return is to make the compiler happy
02090     return static_cast<int16_t>(0);
02091 }
02092 //............................................................................
02093 void QActive::start(uint8_t const prio,
02094                    QEvt const *qSto[], uint32_t const qLen,
02095                    void * const stkSto, uint32_t const stkSize,
02096                    QEvt const * const ie)
02097 {
02098     Q_REQUIRE((static_cast<uint8_t>(0) < prio)
02099               && (prio <= static_cast<uint8_t>(QF_MAX_ACTIVE)));
02100 
02101     m_eQueue.init(qSto, static_cast<QEQueueCtr>(qLen));    // initialize queue
02102     m_prio = prio;
02103     QF::add_(this);                     // make QF aware of this active object
02104 
02105 #if defined(QK_TLS) || defined(QK_EXT_SAVE)
02106     // in the QK port the parameter stkSize is used as the thread flags
02107     m_osObject = static_cast<uint8_t>(stkSize);   // m_osObject contains flags
02108 
02109     // in the QK port the parameter stkSto is used as the thread-local-storage
02110     m_thread   = stkSto;   // contains the pointer to the thread-local-storage
02111 #else
02112     Q_ASSERT((stkSto == static_cast<void *>(0))
02113              && (stkSize == static_cast<uint32_t>(0)));
02114 #endif
02115 
02116     init(ie);                                    // execute initial transition
02117 
02118     QS_FLUSH();                          // flush the trace buffer to the host
02119 }
02120 //............................................................................
02121 void QActive::stop(void) {
02122     QF::remove_(this);                // remove this active object from the QF
02123 }
02124 
02125 QP_END_
02126 
02127 // "qk_sched" ================================================================
02128 /// \brief QK_schedPrio_() and QK_sched_() implementation.
02129 
02130 //............................................................................
02131 // NOTE: the QK scheduler is entered and exited with interrupts DISABLED.
02132 // QK_sched_() is extern "C", so it does not belong to the QP namespace.
02133 //
02134 extern "C" {
02135 
02136 //............................................................................
02137 // NOTE: QK schedPrio_() is entered and exited with interrupts DISABLED
02138 uint8_t QK_schedPrio_(void) {
02139 
02140     uint8_t p = QK_readySet_.findMax();
02141 
02142 #ifdef QK_NO_MUTEX
02143     if (p > QK_currPrio_) {                        // do we have a preemption?
02144 #else                                   // QK priority-ceiling mutexes allowed
02145     if ((p > QK_currPrio_) && (p > QK_ceilingPrio_)) {
02146 #endif
02147     }
02148     else {
02149         p = static_cast<uint8_t>(0);
02150     }
02151     return p;
02152 }
02153 //............................................................................
02154 void QK_sched_(uint8_t p) {
02155 
02156     uint8_t pin = QK_currPrio_;                   // save the initial priority
02157     QP_ QActive *a;
02158 #ifdef QK_TLS                                    // thread-local storage used?
02159     uint8_t pprev = pin;
02160 #endif
02161     do {
02162         a = QP_ QF::active_[p];                // obtain the pointer to the AO
02163         QK_currPrio_ = p;            // this becomes the current task priority
02164 
02165 #ifdef QK_TLS                                    // thread-local storage used?
02166         if (p != pprev) {                          // are we changing threads?
02167             QK_TLS(a);                      // switch new thread-local storage
02168             pprev = p;
02169         }
02170 #endif
02171         QS_BEGIN_NOCRIT_(QP_ QS_QK_SCHEDULE, QP_ QS::aoObj_, a)
02172             QS_TIME_();                                           // timestamp
02173             QS_U8_(p);                    // the priority of the active object
02174             QS_U8_(pin);                             // the preempted priority
02175         QS_END_NOCRIT_()
02176 
02177         QF_INT_ENABLE();                  // unconditionally enable interrupts
02178 
02179         QP_ QEvt const *e = a->get_();       // get the next event for this AO
02180         a->dispatch(e);                               // dispatch e to this AO
02181         QP_ QF::gc(e);              // garbage collect the event, if necessary
02182 
02183                         // determine the next highest-priority AO ready to run
02184         QF_INT_DISABLE();                                // disable interrupts
02185         p = QK_readySet_.findMax();
02186 
02187 #ifdef QK_NO_MUTEX
02188     } while (p > pin);             // is the new priority higher than initial?
02189 #else                                   // QK priority-ceiling mutexes allowed
02190     } while ((p > pin) && (p > QK_ceilingPrio_));
02191 #endif
02192 
02193     QK_currPrio_ = pin;                        // restore the initial priority
02194 
02195 #ifdef QK_TLS                                    // thread-local storage used?
02196     if (pin != static_cast<uint8_t>(0)) { // no extended context for idle loop
02197         a = QP_ QF::active_[pin];           // the pointer to the preempted AO
02198         QK_TLS(a);                                 // restore the original TLS
02199     }
02200 #endif
02201 }
02202 
02203 }                                                                // extern "C"
02204 
02205 #ifndef QK_NO_MUTEX
02206 
02207 // "qk_mutex.cpp" ============================================================
02208 /// \brief QK::mutexLock()/QK::mutexUnlock() implementation.
02209 
02210 // package-scope objects -----------------------------------------------------
02211 extern "C" {
02212     uint8_t QK_ceilingPrio_;                    // ceiling priority of a mutex
02213 }
02214 
02215 QP_BEGIN_
02216 
02217 //............................................................................
02218 QMutex QK::mutexLock(uint8_t const prioCeiling) {
02219     QF_CRIT_STAT_
02220     QF_CRIT_ENTRY_();
02221     uint8_t mutex = QK_ceilingPrio_; // original QK priority ceiling to return
02222     if (QK_ceilingPrio_ < prioCeiling) {
02223         QK_ceilingPrio_ = prioCeiling;        // raise the QK priority ceiling
02224     }
02225 
02226     QS_BEGIN_NOCRIT_(QS_QK_MUTEX_LOCK,
02227                      static_cast<void *>(0), static_cast<void *>(0))
02228         QS_TIME_();                                               // timestamp
02229         QS_U8_(mutex);                                // the original priority
02230         QS_U8_(QK_ceilingPrio_);               // the current priority ceiling
02231     QS_END_NOCRIT_()
02232 
02233     QF_CRIT_EXIT_();
02234     return mutex;
02235 }
02236 //............................................................................
02237 void QK::mutexUnlock(QMutex mutex) {
02238     QF_CRIT_STAT_
02239     QF_CRIT_ENTRY_();
02240 
02241     QS_BEGIN_NOCRIT_(QS_QK_MUTEX_UNLOCK,
02242                      static_cast<void *>(0), static_cast<void *>(0))
02243         QS_TIME_();                                               // timestamp
02244         QS_U8_(mutex);                                // the original priority
02245         QS_U8_(QK_ceilingPrio_);               // the current priority ceiling
02246     QS_END_NOCRIT_()
02247 
02248     if (QK_ceilingPrio_ > mutex) {
02249         QK_ceilingPrio_ = mutex;         // restore the saved priority ceiling
02250         mutex = QK_schedPrio_();             // reuse 'mutex' to hold priority
02251         if (mutex != static_cast<uint8_t>(0)) {
02252             QK_sched_(mutex);
02253         }
02254     }
02255     QF_CRIT_EXIT_();
02256 }
02257 
02258 QP_END_
02259 
02260 #endif                                                          // QK_NO_MUTEX
02261 
02262 #else                                                         // QK_PREEMPTIVE
02263 
02264 // "qvanilla.cpp" ============================================================
02265 /// \brief "vanilla" cooperative kernel,
02266 /// QActive::start(), QActive::stop(), and QF::run() implementation.
02267 
02268 QP_BEGIN_
02269 
02270 // Package-scope objects -----------------------------------------------------
02271 extern "C" {
02272 #if (QF_MAX_ACTIVE <= 8)
02273     QPSet8  QF_readySet_;                       // ready set of active objects
02274 #else
02275     QPSet64 QF_readySet_;                       // ready set of active objects
02276 #endif
02277 
02278 uint8_t QF_currPrio_;                     ///< current task/interrupt priority
02279 uint8_t QF_intNest_;                              ///< interrupt nesting level
02280 
02281 }                                                                // extern "C"
02282 
02283 //............................................................................
02284 void QF::init(void) {
02285     // nothing to do for the "vanilla" kernel
02286 }
02287 //............................................................................
02288 void QF::stop(void) {
02289     onCleanup();                                           // cleanup callback
02290     // nothing else to do for the "vanilla" kernel
02291 }
02292 //............................................................................
02293 int16_t QF::run(void) {
02294     onStartup();                                           // startup callback
02295 
02296     for (;;) {                                           // the bacground loop
02297         QF_INT_DISABLE();
02298         if (QF_readySet_.notEmpty()) {
02299             uint8_t p = QF_readySet_.findMax();
02300             QActive *a = active_[p];
02301             QF_currPrio_ = p;                     // save the current priority
02302             QF_INT_ENABLE();
02303 
02304             QEvt const *e = a->get_();     // get the next event for this AO
02305             a->dispatch(e);                         // dispatch evt to the HSM
02306             gc(e);       // determine if event is garbage and collect it if so
02307         }
02308         else {
02309             onIdle();                                            // see NOTE01
02310         }
02311     }
02312                       // this unreachable return is to make the compiler happy
02313     return static_cast<int16_t>(0);
02314 }
02315 //............................................................................
02316 void QActive::start(uint8_t const prio,
02317                     QEvt const *qSto[], uint32_t const qLen,
02318                     void * const stkSto, uint32_t const,
02319                     QEvt const * const ie)
02320 {
02321     Q_REQUIRE((u8_0 < prio) && (prio <= static_cast<uint8_t>(QF_MAX_ACTIVE))
02322               && (stkSto == null_void));      // does not need per-actor stack
02323 
02324     m_eQueue.init(qSto, static_cast<QEQueueCtr>(qLen));  // initialize QEQueue
02325     m_prio = prio;                // set the QF priority of this active object
02326     QF::add_(this);                     // make QF aware of this active object
02327     init(ie);                                    // execute initial transition
02328 
02329     QS_FLUSH();                          // flush the trace buffer to the host
02330 }
02331 //............................................................................
02332 void QActive::stop(void) {
02333     QF::remove_(this);
02334 }
02335 
02336 QP_END_
02337 
02338 //////////////////////////////////////////////////////////////////////////////
02339 // NOTE01:
02340 // QF::onIdle() must be called with interrupts DISABLED because the
02341 // determination of the idle condition (no events in the queues) can change
02342 // at any time by an interrupt posting events to a queue. The QF::onIdle()
02343 // MUST enable interrups internally, perhaps at the same time as putting the
02344 // CPU into a power-saving mode.
02345 //
02346 
02347 extern "C" {
02348 
02349 void QK_sched_(uint8_t p) {            // dummy empty definition for qk_port.s
02350     (void)p;
02351 }
02352 
02353 uint8_t QK_schedPrio_(void) {          // dummy empty definition for qk_port.s
02354     return static_cast<uint8_t>(0U);
02355 }
02356 
02357 }                                                                // extern "C"
02358 
02359 #endif                                                        // QK_PREEMPTIVE
02360 
02361 //////////////////////////////////////////////////////////////////////////////
02362 #ifdef Q_SPY
02363 
02364 // "qs_pkg.h" ================================================================
02365 /// \brief Internal (package scope) QS/C++ interface.
02366 
02367 QP_BEGIN_
02368 
02369 /// \brief QS ring buffer counter and offset type
02370 typedef uint16_t QSCtr;
02371 
02372 /// \brief Internal QS macro to insert an un-escaped byte into
02373 /// the QS buffer
02374 ////
02375 #define QS_INSERT_BYTE(b_) \
02376     QS_PTR_AT_(QS_head_) = (b_); \
02377     ++QS_head_; \
02378     if (QS_head_ == QS_end_) { \
02379         QS_head_ = static_cast<QSCtr>(0); \
02380     } \
02381     ++QS_used_;
02382 
02383 /// \brief Internal QS macro to insert an escaped byte into the QS buffer
02384 #define QS_INSERT_ESC_BYTE(b_) \
02385     QS_chksum_ = static_cast<uint8_t>(QS_chksum_ + (b_)); \
02386     if (((b_) == QS_FRAME) || ((b_) == QS_ESC)) { \
02387         QS_INSERT_BYTE(QS_ESC) \
02388         QS_INSERT_BYTE(static_cast<uint8_t>((b_) ^ QS_ESC_XOR)) \
02389     } \
02390     else { \
02391         QS_INSERT_BYTE(b_) \
02392     }
02393 
02394 /// \brief Internal QS macro to insert a escaped checksum byte into
02395 /// the QS buffer
02396 #define QS_INSERT_CHKSUM_BYTE() \
02397     QS_chksum_ = static_cast<uint8_t>(~QS_chksum_); \
02398     if ((QS_chksum_ == QS_FRAME) || (QS_chksum_ == QS_ESC)) { \
02399         QS_INSERT_BYTE(QS_ESC) \
02400         QS_INSERT_BYTE(static_cast<uint8_t>(QS_chksum_ ^ QS_ESC_XOR)) \
02401     } \
02402     else { \
02403         QS_INSERT_BYTE(QS_chksum_) \
02404     }
02405 
02406 
02407 /// \brief Internal QS macro to access the QS ring buffer
02408 ///
02409 /// \note The QS buffer is allocated by the user and is accessed through the
02410 /// pointer QS_ring_, which violates the MISRA-C 2004 Rule 17.4(req), pointer
02411 /// arithmetic other than array indexing. Encapsulating this violation in a
02412 /// macro allows to selectively suppress this specific deviation.
02413 #define QS_PTR_AT_(i_) (QS_ring_[i_])
02414 
02415 
02416 /// \brief Frame character of the QS output protocol
02417 uint8_t const QS_FRAME = static_cast<uint8_t>(0x7E);
02418 
02419 /// \brief Escape character of the QS output protocol
02420 uint8_t const QS_ESC   = static_cast<uint8_t>(0x7D);
02421 
02422 /// \brief Escape modifier of the QS output protocol
02423 ///
02424 /// The escaped byte is XOR-ed with the escape modifier before it is inserted
02425 /// into the QS buffer.
02426 uint8_t const QS_ESC_XOR = static_cast<uint8_t>(0x20);
02427 
02428 #ifndef Q_ROM_BYTE
02429     /// \brief Macro to access a byte allocated in ROM
02430     ///
02431     /// Some compilers for Harvard-architecture MCUs, such as gcc for AVR, do
02432     /// not generate correct code for accessing data allocated in the program
02433     /// space (ROM). The workaround for such compilers is to explictly add
02434     /// assembly code to access each data element allocated in the program
02435     /// space. The macro Q_ROM_BYTE() retrieves a byte from the given ROM
02436     /// address.
02437     ///
02438     /// The Q_ROM_BYTE() macro should be defined for the compilers that
02439     /// cannot handle correctly data allocated in ROM (such as the gcc).
02440     /// If the macro is left undefined, the default definition simply returns
02441     /// the argument and lets the compiler generate the correct code.
02442     #define Q_ROM_BYTE(rom_var_)   (rom_var_)
02443 #endif
02444 
02445 //............................................................................
02446 extern uint8_t *QS_ring_;         ///< pointer to the start of the ring buffer
02447 extern QSCtr QS_end_;                ///< offset of the end of the ring buffer
02448 extern QSCtr QS_head_;         ///< offset to where next byte will be inserted
02449 extern QSCtr QS_tail_;       ///< offset of where next event will be extracted
02450 extern QSCtr QS_used_;       ///< number of bytes currently in the ring buffer
02451 extern uint8_t QS_seq_;                        ///< the record sequence number
02452 extern uint8_t QS_chksum_;             ///< the checksum of the current record
02453 extern uint8_t QS_full_;              ///< the ring buffer is temporarily full
02454 
02455 QP_END_
02456 
02457 
02458 // "qs.cpp" ==================================================================
02459 /// \brief QS internal variables definitions and core QS functions
02460 /// implementations.
02461 
02462 QP_BEGIN_
02463 
02464 //............................................................................
02465 uint8_t QS::glbFilter_[32];                                // global QS filter
02466 
02467 //............................................................................
02468 uint8_t *QS_ring_;                  // pointer to the start of the ring buffer
02469 QSCtr QS_end_;                         // offset of the end of the ring buffer
02470 QSCtr QS_head_;                  // offset to where next byte will be inserted
02471 QSCtr QS_tail_;                 // offset of where next byte will be extracted
02472 QSCtr QS_used_;                // number of bytes currently in the ring buffer
02473 uint8_t QS_seq_;                                 // the record sequence number
02474 uint8_t QS_chksum_;                      // the checksum of the current record
02475 uint8_t QS_full_;                       // the ring buffer is temporarily full
02476 
02477 //............................................................................
02478 char_t const Q_ROM * Q_ROM_VAR QS::getVersion(void) {
02479     uint8_t const u8_zero = static_cast<uint8_t>('0');
02480     static char_t const Q_ROM Q_ROM_VAR version[] = {
02481         static_cast<char_t>(((QP_VERSION >> 12) & 0xFU) + u8_zero),
02482         static_cast<char_t>('.'),
02483         static_cast<char_t>(((QP_VERSION >>  8) & 0xFU) + u8_zero),
02484         static_cast<char_t>('.'),
02485         static_cast<char_t>(((QP_VERSION >>  4) & 0xFU) + u8_zero),
02486         static_cast<char_t>((QP_VERSION         & 0xFU) + u8_zero),
02487         static_cast<char_t>('\0')
02488     };
02489     return version;
02490 }
02491 //............................................................................
02492 void QS::initBuf(uint8_t sto[], uint32_t const stoSize) {
02493     QS_ring_ = &sto[0];
02494     QS_end_  = static_cast<QSCtr>(stoSize);
02495 }
02496 //............................................................................
02497 void QS::filterOn(uint8_t const rec) {
02498     if (rec == QS_ALL_RECORDS) {
02499         uint8_t i;
02500         for (i = static_cast<uint8_t>(0);
02501              i < static_cast<uint8_t>(sizeof(glbFilter_));
02502              ++i)
02503         {
02504             glbFilter_[i] = static_cast<uint8_t>(0xFF);
02505         }
02506     }
02507     else {
02508         glbFilter_[rec >> 3] |=
02509             static_cast<uint8_t>(1U << (rec & static_cast<uint8_t>(0x07)));
02510     }
02511 }
02512 //............................................................................
02513 void QS::filterOff(uint8_t const rec) {
02514     if (rec == QS_ALL_RECORDS) {
02515         uint8_t i;
02516         for (i = static_cast<uint8_t>(0);
02517             i < static_cast<uint8_t>(sizeof(glbFilter_));
02518             ++i)
02519         {
02520             glbFilter_[i] = static_cast<uint8_t>(0);
02521         }
02522     }
02523     else {
02524         glbFilter_[rec >> 3] &= static_cast<uint8_t>(
02525            ~static_cast<uint8_t>((1U << (rec & static_cast<uint8_t>(0x07)))));
02526     }
02527 }
02528 //............................................................................
02529 void QS::begin(uint8_t const rec) {
02530     QS_chksum_ = static_cast<uint8_t>(0);                // clear the checksum
02531     ++QS_seq_;                         // always increment the sequence number
02532     QS_INSERT_ESC_BYTE(QS_seq_)                   // store the sequence number
02533     QS_INSERT_ESC_BYTE(rec)                             // store the record ID
02534 }
02535 //............................................................................
02536 void QS::end(void) {
02537     QS_INSERT_CHKSUM_BYTE()
02538     QS_INSERT_BYTE(QS_FRAME)
02539     if (QS_used_ > QS_end_) {                    // overrun over the old data?
02540         QS_tail_ = QS_head_;                 // shift the tail to the old data
02541         QS_used_ = QS_end_;                        // the whole buffer is used
02542     }
02543 }
02544 //............................................................................
02545 void QS::u8(uint8_t const format, uint8_t const d) {
02546     QS_INSERT_ESC_BYTE(format)
02547     QS_INSERT_ESC_BYTE(d)
02548 }
02549 //............................................................................
02550 void QS::u16(uint8_t const format, uint16_t d) {
02551     QS_INSERT_ESC_BYTE(format)
02552     QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
02553     d >>= 8;
02554     QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
02555 }
02556 //............................................................................
02557 void QS::u32(uint8_t const format, uint32_t d) {
02558     QS_INSERT_ESC_BYTE(format)
02559     QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
02560     d >>= 8;
02561     QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
02562     d >>= 8;
02563     QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
02564     d >>= 8;
02565     QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
02566 }
02567 
02568 QP_END_
02569 
02570 
02571 // "qs_.cpp" =================================================================
02572 /// \brief QS functions for internal use inside QP components
02573 
02574 QP_BEGIN_
02575 
02576 //............................................................................
02577 void const *QS::smObj_;                  // local state machine for QEP filter
02578 void const *QS::aoObj_;                   // local active object for QF filter
02579 void const *QS::mpObj_;                     //  local event pool for QF filter
02580 void const *QS::eqObj_;                      //  local raw queue for QF filter
02581 void const *QS::teObj_;                     //  local time event for QF filter
02582 void const *QS::apObj_;                    //  local object Application filter
02583 
02584 QSTimeCtr QS::tickCtr_;              // tick counter for the QS_QF_TICK record
02585 
02586 //............................................................................
02587 void QS::u8_(uint8_t const d) {
02588     QS_INSERT_ESC_BYTE(d)
02589 }
02590 //............................................................................
02591 void QS::u16_(uint16_t d) {
02592     QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
02593     d >>= 8;
02594     QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
02595 }
02596 //............................................................................
02597 void QS::u32_(uint32_t d) {
02598     QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
02599     d >>= 8;
02600     QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
02601     d >>= 8;
02602     QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
02603     d >>= 8;
02604     QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
02605 }
02606 //............................................................................
02607 void QS::str_(char_t const *s) {
02608     uint8_t b = static_cast<uint8_t>(*s);
02609     while (b != static_cast<uint8_t>(0)) {
02610                                        // ASCII characters don't need escaping
02611         QS_chksum_ = static_cast<uint8_t>(QS_chksum_ + b);
02612         QS_INSERT_BYTE(b)
02613         ++s;
02614         b = static_cast<uint8_t>(*s);
02615     }
02616     QS_INSERT_BYTE(static_cast<uint8_t>(0))
02617 }
02618 //............................................................................
02619 void QS::str_ROM_(char_t const Q_ROM * Q_ROM_VAR s) {
02620     uint8_t b = static_cast<uint8_t>(Q_ROM_BYTE(*s));
02621     while (b != static_cast<uint8_t>(0)) {
02622                                        // ASCII characters don't need escaping
02623         QS_chksum_ = static_cast<uint8_t>(QS_chksum_ + b);
02624         QS_INSERT_BYTE(b)
02625         ++s;
02626         b = static_cast<uint8_t>(Q_ROM_BYTE(*s));
02627     }
02628     QS_INSERT_BYTE(static_cast<uint8_t>(0))
02629 }
02630 
02631 QP_END_
02632 
02633 // "qs_blk.cpp" ==============================================================
02634 /// \brief QS::getBlock() implementation
02635 
02636 QP_BEGIN_
02637 
02638 //............................................................................
02639 // get up to *pn bytes of contiguous memory
02640 uint8_t const *QS::getBlock(uint16_t * const pNbytes) {
02641     uint8_t *block;
02642     if (QS_used_ == static_cast<QSCtr>(0)) {
02643         *pNbytes = static_cast<uint16_t>(0);
02644         block = static_cast<uint8_t *>(0);     // no bytes to return right now
02645     }
02646     else {
02647         QSCtr n = static_cast<QSCtr>(QS_end_ - QS_tail_);
02648         if (n > QS_used_) {
02649             n = QS_used_;
02650         }
02651         if (n > static_cast<QSCtr>(*pNbytes)) {
02652             n = static_cast<QSCtr>(*pNbytes);
02653         }
02654         *pNbytes = static_cast<uint16_t>(n);
02655         QS_used_ = static_cast<QSCtr>(QS_used_ - n);
02656         QSCtr t  = QS_tail_;
02657         QS_tail_ = static_cast<QSCtr>(QS_tail_ + n);
02658         if (QS_tail_ == QS_end_) {
02659             QS_tail_ = static_cast<QSCtr>(0);
02660         }
02661         block = &QS_PTR_AT_(t);
02662     }
02663     return block;
02664 }
02665 
02666 QP_END_
02667 
02668 // "qs_byte.cpp" =============================================================
02669 /// \brief QS::getByte() implementation
02670 
02671 QP_BEGIN_
02672 
02673 //............................................................................
02674 uint16_t QS::getByte(void) {
02675     uint16_t ret;
02676     if (QS_used_ == static_cast<QSCtr>(0)) {
02677         ret = QS_EOD;                                       // set End-Of-Data
02678     }
02679     else {
02680         ret = static_cast<uint16_t>(QS_PTR_AT_(QS_tail_));   // byte to return
02681         ++QS_tail_;                                        // advance the tail
02682         if (QS_tail_ == QS_end_) {                        // tail wrap around?
02683             QS_tail_ = static_cast<QSCtr>(0);
02684         }
02685         --QS_used_;                                      // one less byte used
02686     }
02687     return ret;                                      // return the byte or EOD
02688 }
02689 
02690 QP_END_
02691 
02692 
02693 // "qs_f32.cpp" ==============================================================
02694 /// \brief QS::f32() implementation
02695 
02696 QP_BEGIN_
02697 
02698 //............................................................................
02699 void QS::f32(uint8_t const format, float32_t const d) {
02700     union F32Rep {
02701         float32_t f;
02702         uint32_t  u;
02703     } fu32;
02704     fu32.f = d;
02705 
02706     QS_INSERT_ESC_BYTE(format)
02707     QS_INSERT_ESC_BYTE(static_cast<uint8_t>(fu32.u))
02708     fu32.u >>= 8;
02709     QS_INSERT_ESC_BYTE(static_cast<uint8_t>(fu32.u))
02710     fu32.u >>= 8;
02711     QS_INSERT_ESC_BYTE(static_cast<uint8_t>(fu32.u))
02712     fu32.u >>= 8;
02713     QS_INSERT_ESC_BYTE(static_cast<uint8_t>(fu32.u))
02714 }
02715 
02716 QP_END_
02717 
02718 
02719 // "qs_mem.cpp" ==============================================================
02720 /// \brief QS::mem() implementation
02721 
02722 QP_BEGIN_
02723 
02724 //............................................................................
02725 void QS::mem(uint8_t const *blk, uint8_t size) {
02726     QS_INSERT_BYTE(static_cast<uint8_t>(QS_MEM_T))
02727     QS_chksum_ =
02728         static_cast<uint8_t>(QS_chksum_ + static_cast<uint8_t>(QS_MEM_T));
02729     QS_INSERT_ESC_BYTE(size)
02730     while (size != static_cast<uint8_t>(0)) {
02731         QS_INSERT_ESC_BYTE(*blk)
02732         ++blk;
02733         --size;
02734     }
02735 }
02736 
02737 QP_END_
02738 
02739 
02740 // "qs_str.cpp" ==============================================================
02741 /// \brief QS::str() and QS::str_ROM() implementation
02742 
02743 QP_BEGIN_
02744 
02745 //............................................................................
02746 void QS::str(char_t const *s) {
02747     uint8_t b = static_cast<uint8_t>(*s);
02748     QS_INSERT_BYTE(static_cast<uint8_t>(QS_STR_T))
02749     QS_chksum_ =
02750         static_cast<uint8_t>(QS_chksum_ + static_cast<uint8_t>(QS_STR_T));
02751     while (b != static_cast<uint8_t>(0)) {
02752                                        // ASCII characters don't need escaping
02753         QS_INSERT_BYTE(b)
02754         QS_chksum_ = static_cast<uint8_t>(QS_chksum_ + b);
02755         ++s;
02756         b = static_cast<uint8_t>(*s);
02757     }
02758     QS_INSERT_BYTE(static_cast<uint8_t>(0))
02759 }
02760 //............................................................................
02761 void QS::str_ROM(char_t const Q_ROM * Q_ROM_VAR s) {
02762     uint8_t b = static_cast<uint8_t>(Q_ROM_BYTE(*s));
02763     QS_INSERT_BYTE(static_cast<uint8_t>(QS_STR_T))
02764     QS_chksum_ =
02765         static_cast<uint8_t>(QS_chksum_ + static_cast<uint8_t>(QS_STR_T));
02766     while (b != static_cast<uint8_t>(0)) {
02767                                        // ASCII characters don't need escaping
02768         QS_INSERT_BYTE(b)
02769         QS_chksum_ = static_cast<uint8_t>(QS_chksum_ + b);
02770         ++s;
02771         b = static_cast<uint8_t>(Q_ROM_BYTE(*s));
02772     }
02773     QS_INSERT_BYTE(static_cast<uint8_t>(0))
02774 }
02775 
02776 QP_END_
02777 
02778 #endif                                                                // Q_SPY