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.h Source File

qp.h

00001 //////////////////////////////////////////////////////////////////////////////
00002 // Product: QP/C++ platform-independent interface
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 #ifndef qp_h
00036 #define qp_h
00037 
00038 // "qevt.h" ==================================================================
00039 /// \brief QEvt class and basic macros used by all QP components.
00040 ///
00041 /// This header file must be included, perhaps indirectly, in all modules
00042 /// (*.cpp files) that use any component of QP/C++ (such as QEP, QF, or QK).
00043 
00044 //////////////////////////////////////////////////////////////////////////////
00045 /// \brief The current QP version number
00046 ///
00047 /// \return version of the QP as a hex constant constant 0xXYZZ, where X is
00048 /// a 1-digit major version number, Y is a 1-digit minor version number, and
00049 /// ZZ is a 2-digit release number.
00050 #define QP_VERSION      0x4502U
00051 
00052 #ifndef Q_ROM
00053     /// \brief Macro to specify compiler-specific directive for placing a
00054     /// constant object in ROM.
00055     ///
00056     /// Many compilers for Harvard-architecture MCUs provide non-stanard
00057     /// extensions to support placement of objects in different memories.
00058     /// In order to conserve the precious RAM, QP uses the Q_ROM macro for
00059     /// all constant objects that can be allocated in ROM.
00060     ///
00061     /// To override the following empty definition, you need to define the
00062     /// Q_ROM macro in the qep_port.h header file. Some examples of valid
00063     /// Q_ROM macro definitions are: __code (IAR 8051 compiler), code (Keil
00064     /// Cx51 compiler), PROGMEM (gcc for AVR), __flash (IAR for AVR).
00065     #define Q_ROM
00066 #endif
00067 #ifndef Q_ROM_VAR            // if NOT defined, provide the default definition
00068     /// \brief Macro to specify compiler-specific directive for accessing a
00069     /// constant object in ROM.
00070     ///
00071     /// Many compilers for MCUs provide different size pointers for
00072     /// accessing objects in various memories. Constant objects allocated
00073     /// in ROM (see #Q_ROM macro) often mandate the use of specific-size
00074     /// pointers (e.g., far pointers) to get access to ROM objects. The
00075     /// macro Q_ROM_VAR specifies the kind of the pointer to be used to access
00076     /// the ROM objects.
00077     ///
00078     /// To override the following empty definition, you need to define the
00079     /// Q_ROM_VAR macro in the qep_port.h header file. An example of valid
00080     /// Q_ROM_VAR macro definition is: __far (Freescale HC(S)08 compiler).
00081     #define Q_ROM_VAR
00082 #endif
00083 #ifndef Q_ROM_BYTE
00084     /// \brief Macro to access a byte allocated in ROM
00085     ///
00086     /// Some compilers for Harvard-architecture MCUs, such as gcc for AVR, do
00087     /// not generate correct code for accessing data allocated in the program
00088     /// space (ROM). The workaround for such compilers is to explictly add
00089     /// assembly code to access each data element allocated in the program
00090     /// space. The macro Q_ROM_BYTE() retrieves a byte from the given ROM
00091     /// address.
00092     ///
00093     /// The Q_ROM_BYTE() macro should be defined for the compilers that
00094     /// cannot handle correctly data allocated in ROM (such as the gcc).
00095     /// If the macro is left undefined, the default definition simply returns
00096     /// the argument and lets the compiler generate the correct code.
00097     #define Q_ROM_BYTE(rom_var_)   (rom_var_)
00098 #endif
00099 
00100 #ifndef Q_SIGNAL_SIZE
00101     /// \brief The size (in bytes) of the signal of an event. Valid values:
00102     /// 1, 2, or 4; default 1
00103     ///
00104     /// This macro can be defined in the QEP port file (qep_port.h) to
00105     /// configure the ::QSignal type. When the macro is not defined, the
00106     /// default of 1 byte is chosen.
00107     #define Q_SIGNAL_SIZE 2
00108 #endif
00109 
00110 #ifndef Q_NNAMESPACE
00111 
00112     /// \brief begin of the namespace QP
00113     ///
00114     /// \note defines to nothing if #Q_USE_NAMESPACE is undefined
00115     #define QP_BEGIN_  namespace QP {
00116 
00117     /// \brief end of the namespace QP
00118     ///
00119     /// \note defines to nothing if #Q_USE_NAMESPACE is undefined
00120     #define QP_END_    }
00121 
00122     /// \brief namespace QP prefix
00123     ///
00124     /// \note defines to nothing if #Q_USE_NAMESPACE is undefined
00125     #define QP_        QP::
00126 
00127 #else
00128 
00129     #define QP_BEGIN_
00130     #define QP_END_
00131     #define QP_
00132 
00133 #endif
00134 
00135 QP_BEGIN_
00136 
00137 #if (Q_SIGNAL_SIZE == 1)
00138     typedef uint8_t QSignal;
00139 #elif (Q_SIGNAL_SIZE == 2)
00140     /// \brief QSignal represents the signal of an event.
00141     ///
00142     /// The relationship between an event and a signal is as follows. A signal
00143     /// in UML is the specification of an asynchronous stimulus that triggers
00144     /// reactions [<A HREF="http://www.omg.org/docs/ptc/03-08-02.pdf">UML
00145     /// document ptc/03-08-02</A>], and as such is an essential part of an
00146     /// event. (The signal conveys the type of the occurrence-what happened?)
00147     /// However, an event can also contain additional quantitative information
00148     /// about the occurrence in form of event parameters. Please refer to the
00149     typedef uint16_t QSignal;
00150 #elif (Q_SIGNAL_SIZE == 4)
00151     typedef uint32_t QSignal;
00152 #else
00153     #error "Q_SIGNAL_SIZE defined incorrectly, expected 1, 2, or 4"
00154 #endif
00155 
00156 #ifdef Q_EVT_CTOR               // Provide the constructor for the QEvt class?
00157 
00158     //////////////////////////////////////////////////////////////////////////
00159     /// \brief QEvt base class.
00160     ///
00161     /// QEvt represents events without parameters and serves as the base class
00162     /// for derivation of events with parameters.
00163     ///
00164     /// The following example illustrates how to add an event parameter by
00165     /// inheriting from the QEvt class.
00166     /// \include qep_qevent.cpp
00167     class QEvt {
00168     public:
00169         QSignal sig;                         ///< signal of the event instance
00170 
00171         QEvt(QSignal const s)           // poolId_ intentionally uninitialized
00172           : sig(s) {}
00173 
00174 #ifdef Q_EVT_VIRTUAL
00175         virtual ~QEvt() {}                               // virtual destructor
00176 #endif
00177 
00178     private:
00179         uint8_t poolId_;                     ///< pool ID (0 for static event)
00180         uint8_t refCtr_;                                ///< reference counter
00181 
00182         friend class QF;
00183         friend class QTimeEvt;
00184         friend uint8_t QF_EVT_POOL_ID_ (QEvt const * const e);
00185         friend uint8_t QF_EVT_REF_CTR_ (QEvt const * const e);
00186         friend void QF_EVT_REF_CTR_INC_(QEvt const * const e);
00187         friend void QF_EVT_REF_CTR_DEC_(QEvt const * const e);
00188     };
00189 
00190 #else                                    // QEvt is a POD (Plain Old Datatype)
00191 
00192     struct QEvt {
00193         QSignal sig;                         ///< signal of the event instance
00194         uint8_t poolId_;                     ///< pool ID (0 for static event)
00195         uint8_t refCtr_;                                ///< reference counter
00196     };
00197 
00198 #endif                                                           // Q_EVT_CTOR
00199 
00200 QP_END_
00201 
00202 //////////////////////////////////////////////////////////////////////////////
00203 /// helper macro to calculate static dimension of a 1-dim array \a array_
00204 #define Q_DIM(array_) (sizeof(array_) / sizeof(array_[0]))
00205 
00206 //////////////////////////////////////////////////////////////////////////////
00207 // typedefs for basic numerical types; MISRA-C++ 2008 rule 3-9-2(req).
00208 
00209 /// \brief typedef for character strings.
00210 ///
00211 /// This typedef specifies character type for exclusive use in character
00212 /// strings. Use of this type, rather than plain 'char', is in compliance
00213 /// with the MISRA-C 2004 Rules 6.1(req), 6.3(adv).
00214 ///
00215 typedef char char_t;
00216 
00217 /// typedef for 32-bit IEEE 754 floating point numbers
00218 typedef float float32_t;
00219 
00220 /// typedef for 64-bit IEEE 754 floating point numbers
00221 typedef double float64_t;
00222 
00223 /// typedef for enumerations used for event signals
00224 typedef int enum_t;
00225 
00226 /// \brief Perform cast from unsigned integer \a uint_ to pointer
00227 /// of type \a type_.
00228 ///
00229 /// This macro encapsulates the cast to (type_ *), which QP ports or
00230 /// application might use to access embedded hardware registers.
00231 /// Such uses can trigger PC-Lint "Note 923: cast from int to pointer"
00232 /// and this macro helps to encapsulate this deviation.
00233 ///
00234 #define Q_UINT2PTR_CAST(type_, uint_)  (reinterpret_cast<type_ *>(uint_))
00235 
00236 /// \brief Initializer of static constant QEvt instances
00237 ///
00238 /// This macro encapsulates the ugly casting of enumerated signals
00239 /// to QSignal and constants for QEvt.poolID and QEvt.refCtr_.
00240 ///
00241 #define QEVT_INITIALIZER(sig_) { static_cast<QP_ QSignal>(sig_), \
00242     static_cast<uint8_t>(0), static_cast<uint8_t>(0) }
00243 
00244 //////////////////////////////////////////////////////////////////////////////
00245 // facilities for backwards compatibility
00246 //
00247 #ifndef Q_NQEVENT
00248 //    typedef struct QEvt QEvent;
00249     #define QEvent QEvt
00250 #endif
00251 
00252 
00253 // "qep.h" ===================================================================
00254 /// \brief QEP/C++ platform-independent public interface.
00255 ///
00256 /// This header file must be included directly or indirectly
00257 /// in all modules (*.cpp files) that use QEP/C++.
00258 
00259 /// \brief Designates a target for an initial or regular transition.
00260 /// Q_TRAN() can be used both in the FSMs and HSMs.
00261 ///
00262 /// \include qep_qtran.c
00263 ///
00264 #define Q_TRAN(target_)     (me->tran(Q_STATE_CAST(target_)))
00265 
00266 /// \brief Designates the superstate of a given state in an HSM.
00267 ///
00268 /// \include qep_qhsm.c
00269 ///
00270 #define Q_SUPER(super_)     (me->super(Q_STATE_CAST(super_)))
00271 
00272 /// \brief Perform cast to QStateHandler.
00273 ///
00274 /// This macro encapsulates the cast of a specific state handler function
00275 /// pointer to QStateHandler, which violates MISRA-C 2004 rule 11.4(advisory).
00276 /// This macro helps to localize this deviation.
00277 ///
00278 #define Q_STATE_CAST(handler_) \
00279     (reinterpret_cast<QP_ QStateHandler>(handler_))
00280 
00281 /// \brief Perform downcast of an event onto a subclass of QEvt \a class_
00282 ///
00283 /// This macro encapsulates the downcast of QEvt pointers, which violates
00284 /// MISRA-C 2004 rule 11.4(advisory). This macro helps to localize this
00285 /// deviation.
00286 ///
00287 #define Q_EVT_CAST(class_)   (static_cast<class_ const *>(e))
00288 
00289 //////////////////////////////////////////////////////////////////////////////
00290 QP_BEGIN_
00291 
00292 /// \brief Provides miscellaneous QEP services.
00293 class QEP {
00294 public:
00295     /// \brief get the current QEP version number string
00296     ///
00297     /// \return version of the QEP as a constant 6-character string of the
00298     /// form x.y.zz, where x is a 1-digit major version number, y is a
00299     /// 1-digit minor version number, and zz is a 2-digit release number.
00300     static char_t const Q_ROM * Q_ROM_VAR getVersion(void);
00301 };
00302 
00303 //////////////////////////////////////////////////////////////////////////////
00304 
00305                        /// \brief Type returned from  a state-handler function
00306 typedef uint8_t QState;
00307                                   /// \brief pointer to state-handler function
00308 typedef QState (*QStateHandler)(void * const me, QEvt const * const e);
00309 
00310 //////////////////////////////////////////////////////////////////////////////
00311 /// \brief Value returned by a state-handler function when it handles
00312 /// the event.
00313 QState const Q_RET_HANDLED = static_cast<QState>(0);
00314 
00315 /// \brief Value returned by a non-hierarchical state-handler function when
00316 /// it ignores (does not handle) the event.
00317 QState const Q_RET_IGNORED = static_cast<QState>(1);
00318 
00319 /// \brief Value returned by a state-handler function when it takes a
00320 /// regular state transition.
00321 QState const Q_RET_TRAN    = static_cast<QState>(2);
00322 
00323 /// \brief Value returned by a state-handler function when it forwards
00324 /// the event to the superstate to handle.
00325 QState const Q_RET_SUPER   = static_cast<QState>(3);
00326 
00327 /// \brief Value returned by a state-handler function when a guard
00328 /// condition prevents it from handling the event.
00329 ///
00330 QState const Q_RET_UNHANDLED = static_cast<QState>(4);
00331 
00332 
00333 /// Offset or the user signals
00334 enum_t const Q_USER_SIG    = static_cast<enum_t>(4);
00335 
00336 
00337 //////////////////////////////////////////////////////////////////////////////
00338 /// \brief Finite State Machine base class
00339 ///
00340 /// QFsm represents a traditional non-hierarchical Finite State Machine (FSM)
00341 /// without state hierarchy, but with entry/exit actions.
00342 ///
00343 /// QFsm is also a base structure for the ::QHsm class.
00344 ///
00345 /// \note QFsm is not intended to be instantiated directly, but rather serves
00346 /// as the base class for derivation of state machines in the application
00347 /// code.
00348 ///
00349 /// The following example illustrates how to derive a state machine class
00350 /// from QFsm.
00351 /// \include qep_qfsm.cpp
00352 class QFsm {
00353 private:
00354     QStateHandler m_state;          ///< current active state (state-variable)
00355     QStateHandler m_temp;  ///< temporary state: target of tran. or superstate
00356 
00357 public:
00358     /// \brief virtual destructor
00359     virtual ~QFsm();
00360 
00361     /// \brief Performs the second step of FSM initialization by triggering
00362     /// the top-most initial transition.
00363     ///
00364     /// The argument \a e is constant pointer to ::QEvt or a class
00365     /// derived from ::QEvt.
00366     ///
00367     /// \note Must be called only ONCE before QFsm::dispatch()
00368     ///
00369     /// The following example illustrates how to initialize a FSM, and
00370     /// dispatch events to it:
00371     /// \include qep_qfsm_use.cpp
00372     void init(QEvt const * const e = static_cast<QEvt const *>(0));
00373 
00374     /// \brief Dispatches an event to a FSM
00375     ///
00376     /// Processes one event at a time in Run-to-Completion (RTC) fashion.
00377     /// The argument \a e is a constant pointer the ::QEvt or a
00378     /// class derived from ::QEvt.
00379     ///
00380     /// \note Must be called after QFsm::init().
00381     ///
00382     /// \sa example for QFsm::init()
00383     void dispatch(QEvt const * const e);
00384 
00385 protected:
00386     /// \brief Protected constructor of a FSM.
00387     ///
00388     /// Performs the first step of FSM initialization by assigning the
00389     /// initial pseudostate to the currently active state of the state
00390     /// machine.
00391     ///
00392     /// \note The constructor is protected to prevent direct instantiating
00393     /// of QFsm objects. This class is intended for subclassing only.
00394     ///
00395     /// \sa The ::QFsm example illustrates how to use the QHsm constructor
00396     /// in the constructor initializer list of the derived state machines.
00397     QFsm(QStateHandler const initial)
00398       : m_state(Q_STATE_CAST(0)),
00399         m_temp(initial)
00400     {}
00401 
00402     /// \brief Return the current active state.
00403     QStateHandler state(void) const {
00404         return m_state;
00405     }
00406 
00407     /// \brief Inline function to specify the return of a state-handler
00408     /// when it igonres (does not handle in any way) the event.
00409     static QState Q_IGNORED(void) { return Q_RET_IGNORED; }
00410 
00411     /// \brief Inline function to specify the return of a state-handler
00412     /// when it handles the event.
00413     ///
00414     /// \include qep_qhsm.cpp
00415     static QState Q_HANDLED(void) { return Q_RET_HANDLED; }
00416 
00417     /// \brief Macro to specify the return of a state-handler function when
00418     /// it attempts to handle the event but a guard condition evaluates to
00419     /// false and there is no other explicit way of handling the event.
00420     static QState Q_UNHANDLED(void) { return Q_RET_UNHANDLED; }
00421 
00422     /// \brief internal helper function to record a state transition
00423     QState tran(QStateHandler const target) {
00424         m_temp = target;
00425         return Q_RET_TRAN;
00426     }
00427 
00428     enum ReservedFsmSignals  {
00429         Q_ENTRY_SIG = 1,                         ///< signal for entry actions
00430         Q_EXIT_SIG                                ///< signal for exit actions
00431     };
00432 };
00433 
00434 //////////////////////////////////////////////////////////////////////////////
00435 /// \brief Hierarchical State Machine base class
00436 ///
00437 /// QHsm represents a Hierarchical Finite State Machine (HSM). QHsm derives
00438 /// from the ::QFsm class and extends the capabilities of a basic FSM
00439 /// with state hierarchy.
00440 ///
00441 /// \note QHsm is not intended to be instantiated directly, but rather serves
00442 /// as the base structure for derivation of state machines in the application
00443 /// code.
00444 ///
00445 /// The following example illustrates how to derive a state machine class
00446 /// from QHsm.
00447 /// \include qep_qhsm.cpp
00448 class QHsm {
00449 private:
00450     QStateHandler m_state;          ///< current active state (state-variable)
00451     QStateHandler m_temp;  ///< temporary state: target of tran. or superstate
00452 
00453 public:
00454     /// \brief virtual destructor
00455     virtual ~QHsm();
00456 
00457     /// \brief Performs the second step of HSM initialization by triggering
00458     /// the top-most initial transition.
00459     ///
00460     /// \param e constant pointer ::QEvt or a class derived from ::QEvt
00461     /// \note Must be called only ONCE before QHsm::dispatch()
00462     ///
00463     /// The following example illustrates how to initialize a HSM, and
00464     /// dispatch events to it:
00465     /// \include qep_qhsm_use.cpp
00466     void init(QEvt const * const e = static_cast<QEvt const *>(0));
00467 
00468     /// \brief Dispatches an event to a HSM
00469     ///
00470     /// Processes one event at a time in Run-to-Completion (RTC) fashion.
00471     /// The argument \a e is a constant pointer the ::QEvt or a
00472     /// class derived from ::QEvt.
00473     ///
00474     /// \note Must be called after QHsm::init().
00475     ///
00476     /// \sa example for QHsm::init()
00477     void dispatch(QEvt const * const e);
00478 
00479     /// \brief Tests if a given state is part of the current active state
00480     /// configuratioin
00481     ///
00482     /// \param state is a pointer to the state handler function, e.g.,
00483     /// &QCalc::on.
00484     bool isIn(QStateHandler const s);
00485 
00486 protected:
00487     /// \brief Protected constructor of a HSM.
00488     ///
00489     /// Performs the first step of HSM initialization by assigning the
00490     /// initial pseudostate to the currently active state of the state
00491     /// machine.
00492     ///
00493     /// \note The constructor is protected to prevent direct instantiating
00494     /// of QHsm objects. This class is intended for subclassing only.
00495     ///
00496     /// \sa The ::QHsm example illustrates how to use the QHsm constructor
00497     /// in the constructor initializer list of the derived state machines.
00498     /// \sa QFsm::QFsm()
00499     QHsm(QStateHandler const initial)
00500       : m_state(Q_STATE_CAST(&QHsm::top)),
00501         m_temp(initial)
00502     {}
00503 
00504     /// \brief Return the current active state.
00505     QStateHandler state(void) const {
00506         return m_state;
00507     }
00508 
00509     /// \brief the top-state.
00510     ///
00511     /// QHsm::top() is the ultimate root of state hierarchy in all HSMs
00512     /// derived from ::QHsm. This state handler always returns (QSTATE)0,
00513     /// which means that it "handles" all events.
00514     ///
00515     /// \sa Example of the QCalc::on() state handler.
00516     static QState top(void * const me, QEvt const * const e);
00517 
00518     /// \brief Inline function to specify the return of a state-handler
00519     /// when it handles the event.
00520     ///
00521     /// \include qep_qhsm.cpp
00522     static QState Q_HANDLED(void) { return Q_RET_HANDLED; }
00523 
00524     /// \brief Macro to specify the return of a state-handler function when
00525     /// it attempts to handle the event but a guard condition evaluates to
00526     /// false and there is no other explicit way of handling the event.
00527     static QState Q_UNHANDLED(void) { return Q_RET_UNHANDLED; }
00528 
00529     /// \brief internal helper function to record a state transition
00530     QState tran(QStateHandler const target) {
00531         m_temp = target;
00532         return Q_RET_TRAN;
00533     }
00534 
00535     /// \brief internal helper function to record the superstate
00536     QState super(QStateHandler const superstate) {
00537         m_temp = superstate;
00538         return Q_RET_SUPER;
00539     }
00540 
00541     enum ReservedHsmSignals  {
00542         Q_ENTRY_SIG = 1,                         ///< signal for entry actions
00543         Q_EXIT_SIG,                               ///< signal for exit actions
00544         Q_INIT_SIG                  ///< signal for nested initial transitions
00545     };
00546 };
00547 
00548 //////////////////////////////////////////////////////////////////////////////
00549 
00550 QP_END_
00551 
00552 // "qequeue.h" ===============================================================
00553 /// \brief platform-independent event queue interface.
00554 ///
00555 /// This header file must be included in all QF ports that use native QF
00556 /// event queue implementation. Also, this file is needed when the "raw"
00557 /// thread-safe queues are used for communication between active objects
00558 /// and non-framework entities, such as ISRs, device drivers, or legacy
00559 /// code.
00560 
00561 #ifndef QF_EQUEUE_CTR_SIZE
00562 
00563     /// \brief The size (in bytes) of the ring-buffer counters used in the
00564     /// native QF event queue implementation. Valid values: 1, 2, or 4;
00565     /// default 1.
00566     ///
00567     /// This macro can be defined in the QF port file (qf_port.h) to
00568     /// configure the ::QEQueueCtr type. Here the macro is not defined so the
00569     /// default of 1 byte is chosen.
00570     #define QF_EQUEUE_CTR_SIZE 1
00571 #endif
00572 
00573 QP_BEGIN_
00574 
00575 #if (QF_EQUEUE_CTR_SIZE == 1)
00576     /// \brief The data type to store the ring-buffer counters based on
00577     /// the macro #QF_EQUEUE_CTR_SIZE.
00578     ///
00579     /// The dynamic range of this data type determines the maximum length
00580     /// of the ring buffer managed by the native QF event queue.
00581     typedef uint8_t QEQueueCtr;
00582 #elif (QF_EQUEUE_CTR_SIZE == 2)
00583     typedef uint16_t QEQueueCtr;
00584 #elif (QF_EQUEUE_CTR_SIZE == 4)
00585     typedef uint32_t QEQueueCtr;
00586 #else
00587     #error "QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1, 2, or 4"
00588 #endif
00589 
00590 
00591 //////////////////////////////////////////////////////////////////////////////
00592 /// \brief Native QF Event Queue class
00593 ///
00594 /// This structure describes the native QF event queue, which can be used as
00595 /// the event queue for active objects, or as a simple "raw" event queue for
00596 /// thread-safe event passing among non-framework entities, such as ISRs,
00597 /// device drivers, or other third-party components.
00598 ///
00599 /// The native QF event queue is configured by defining the macro
00600 /// #QF_EQUEUE_TYPE as ::QEQueue in the specific QF port header file.
00601 ///
00602 /// The ::QEQueue structure contains only data members for managing an event
00603 /// queue, but does not contain the storage for the queue buffer, which must
00604 /// be provided externally during the queue initialization.
00605 ///
00606 /// The event queue can store only event pointers, not the whole events. The
00607 /// internal implementation uses the standard ring-buffer plus one external
00608 /// location that optimizes the queue operation for the most frequent case
00609 /// of empty queue.
00610 ///
00611 /// The ::QEQueue structure is used with two sets of functions. One set is for
00612 /// the active object event queue, which needs to block the active object
00613 /// task when the event queue is empty and unblock it when events are posted
00614 /// to the queue. The interface for the native active object event queue
00615 /// consists of the following functions: QActive::postFIFO_(),
00616 /// QActive::postLIFO_(), and QActive::get_(). Additionally the function
00617 /// QEQueue_init() is used to initialize the queue.
00618 ///
00619 /// The other set of functions, uses this structure as a simple "raw" event
00620 /// queue to pass events between entities other than active objects, such as
00621 /// ISRs. The "raw" event queue is not capable of blocking on the get()
00622 /// operation, but is still thread-safe because it uses QF critical section
00623 /// to protect its integrity. The interface for the "raw" thread-safe queue
00624 /// consists of the following functions: QEQueue::postFIFO(),
00625 /// QEQueue::postLIFO(), and QEQueue::get(). Additionally the function
00626 /// QEQueue::init() is used to initialize the queue.
00627 ///
00628 /// \note Most event queue operations (both the active object queues and
00629 /// the "raw" queues) internally use  the QF critical section. You should be
00630 /// careful not to invoke those operations from other critical sections when
00631 /// nesting of critical sections is not supported.
00632 class QEQueue {
00633 private:
00634 
00635     /// \brief pointer to event at the front of the queue
00636     ///
00637     /// All incoming and outgoing events pass through the m_frontEvt location.
00638     /// When the queue is empty (which is most of the time), the extra
00639     /// m_frontEvt location allows to bypass the ring buffer altogether,
00640     /// greatly optimizing the performance of the queue. Only bursts of events
00641     /// engage the ring buffer.
00642     ///
00643     /// The additional role of this attribute is to indicate the empty status
00644     /// of the queue. The queue is empty if the m_frontEvt location is NULL.
00645     QEvt const *m_frontEvt;
00646 
00647     /// \brief pointer to the start of the ring buffer
00648     QEvt const **m_ring;
00649 
00650     /// \brief offset of the end of the ring buffer from the start of the
00651     /// buffer m_ring
00652     QEQueueCtr m_end;
00653 
00654     /// \brief offset to where next event will be inserted into the buffer
00655     QEQueueCtr m_head;
00656 
00657     /// \brief offset of where next event will be extracted from the buffer
00658     QEQueueCtr m_tail;
00659 
00660     /// \brief number of free events in the ring buffer
00661     QEQueueCtr m_nFree;
00662 
00663     /// \brief minimum number of free events ever in the ring buffer.
00664     ///
00665     /// \note this attribute remembers the low-watermark of the ring buffer,
00666     /// which provides a valuable information for sizing event queues.
00667     /// \sa QF::getQueueMargin().
00668     QEQueueCtr m_nMin;
00669 
00670 public:
00671 
00672     /// \brief Initializes the native QF event queue
00673     ///
00674     /// The parameters are as follows: \a qSto[] is the ring buffer storage,
00675     /// \a qLen is the length of the ring buffer in the units of event-
00676     /// pointers.
00677     ///
00678     /// \note The actual capacity of the queue is qLen + 1, because of the
00679     /// extra location fornEvt_.
00680     void init(QEvt const *qSto[], QEQueueCtr const qLen);
00681 
00682     /// \brief "raw" thread-safe QF event queue implementation for the
00683     /// First-In-First-Out (FIFO) event posting. You can call this function
00684     /// from any task context or ISR context. Please note that this function
00685     /// uses internally a critical section.
00686     ///
00687     /// \note The function raises an assertion if the native QF queue becomes
00688     /// full and cannot accept the event.
00689     ///
00690     /// \sa QEQueue::postLIFO(), QEQueue::get()
00691     void postFIFO(QEvt const * const e);
00692 
00693     /// \brief "raw" thread-safe QF event queue implementation for the
00694     /// First-In-First-Out (FIFO) event posting. You can call this function
00695     /// from any task context or ISR context. Please note that this function
00696     ///  uses internally a critical section.
00697     ///
00698     /// \note The function raises an assertion if the native QF queue becomes
00699     /// full and cannot accept the event.
00700     ///
00701     /// \sa QEQueue::postLIFO(), QEQueue::get()
00702     void postLIFO(QEvt const * const e);
00703 
00704     /// \brief "raw" thread-safe QF event queue implementation for the
00705     /// Last-In-First-Out (LIFO) event posting.
00706     ///
00707     /// \note The LIFO policy should be used only with great caution because
00708     /// it alters order of events in the queue.
00709     /// \note The function raises an assertion if the native QF queue becomes
00710     /// full and cannot accept the event. You can call this function from
00711     /// any task context or ISR context. Please note that this function uses
00712     /// internally a critical section.
00713     ///
00714     /// \sa QEQueue::postFIFO(), QEQueue::get()
00715     QEvt const *get(void);
00716 
00717     /// \brief "raw" thread-safe QF event queue operation for
00718     /// obtaining the number of free entries still available in the queue.
00719     ///
00720     /// \note This operation needs to be used with caution because the
00721     /// number of free entries can change unexpectedly. The main intent for
00722     /// using this operation is in conjunction with event deferral. In this
00723     /// case the queue is accessed only from a single thread (by a single AO),
00724     /// so the number of free entries cannot change unexpectedly.
00725     ///
00726     /// \sa QActive::defer(), QActive::recall()
00727     QEQueueCtr getNFree(void) const {
00728         return m_nFree;
00729     }
00730 
00731 private:
00732     friend class QF;
00733     friend class QActive;
00734 };
00735 
00736 QP_END_
00737 
00738 // "qmpool.h" ================================================================
00739 /// \brief platform-independent memory pool interface.
00740 ///
00741 /// This header file must be included in all QF ports that use native QF
00742 /// memory pool implementation.
00743 
00744 #ifndef QF_MPOOL_SIZ_SIZE
00745     /// \brief macro to override the default ::QMPoolSize size.
00746     /// Valid values 1, 2, or 4; default 2
00747     #define QF_MPOOL_SIZ_SIZE 2
00748 #endif
00749 
00750 #ifndef QF_MPOOL_CTR_SIZE
00751 
00752     /// \brief macro to override the default QMPoolCtr size.
00753     /// Valid values 1, 2, or 4; default 2
00754     #define QF_MPOOL_CTR_SIZE 2
00755 #endif
00756 
00757 //////////////////////////////////////////////////////////////////////////////
00758 QP_BEGIN_
00759 
00760 #if (QF_MPOOL_SIZ_SIZE == 1)
00761     /// \brief The data type to store the block-size based on the macro
00762     /// #QF_MPOOL_SIZ_SIZE.
00763     ///
00764     /// The dynamic range of this data type determines the maximum size
00765     /// of blocks that can be managed by the native QF event pool.
00766     typedef uint8_t QMPoolSize;
00767 #elif (QF_MPOOL_SIZ_SIZE == 2)
00768 
00769     typedef uint16_t QMPoolSize;
00770 #elif (QF_MPOOL_SIZ_SIZE == 4)
00771     typedef uint32_t QMPoolSize;
00772 #else
00773     #error "QF_MPOOL_SIZ_SIZE defined incorrectly, expected 1, 2, or 4"
00774 #endif
00775 
00776 #if (QF_MPOOL_CTR_SIZE == 1)
00777     /// \brief The data type to store the block-counter based on the macro
00778     /// #QF_MPOOL_CTR_SIZE.
00779     ///
00780     /// The dynamic range of this data type determines the maximum number
00781     /// of blocks that can be stored in the pool.
00782     typedef uint8_t QMPoolCtr;
00783 #elif (QF_MPOOL_CTR_SIZE == 2)
00784     typedef uint16_t QMPoolCtr;
00785 #elif (QF_MPOOL_CTR_SIZE == 4)
00786     typedef uint32_t QMPoolCtr;
00787 #else
00788     #error "QF_MPOOL_CTR_SIZE defined incorrectly, expected 1, 2, or 4"
00789 #endif
00790 
00791 //////////////////////////////////////////////////////////////////////////////
00792 /// \brief Native QF memory pool class
00793 ///
00794 /// This class describes the native QF memory pool, which can be used as
00795 /// the event pool for dynamic event allocation, or as a fast, deterministic
00796 /// fixed block-size heap for any other objects in your application.
00797 ///
00798 /// The ::QMPool structure contains only data members for managing a memory
00799 /// pool, but does not contain the pool storage, which must be provided
00800 /// externally during the pool initialization.
00801 ///
00802 /// The native QF event pool is configured by defining the macro
00803 /// #QF_EPOOL_TYPE_ as QEQueue in the specific QF port header file.
00804 class QMPool {
00805 private:
00806 
00807     /// start of the memory managed by this memory pool
00808     void *m_start;
00809 
00810     /// end of the memory managed by this memory pool
00811     void *m_end;
00812 
00813     /// linked list of free blocks
00814     void *m_free;
00815 
00816     ///  maximum block size (in bytes)
00817     QMPoolSize m_blockSize;
00818 
00819     /// total number of blocks
00820     QMPoolCtr m_nTot;
00821 
00822     /// number of free blocks remaining
00823     QMPoolCtr m_nFree;
00824 
00825     /// minimum number of free blocks ever present in this pool
00826     ///
00827     /// \note this attribute remembers the low watermark of the pool,
00828     /// which provides a valuable information for sizing event pools.
00829     /// \sa QF::getPoolMargin().
00830     QMPoolCtr m_nMin;
00831 
00832 public:
00833 
00834     /// \brief Initializes the native QF event pool
00835     ///
00836     /// The parameters are as follows: \a poolSto is the pool storage,
00837     /// \a poolSize is the size of the pool storage in bytes, and
00838     /// \a blockSize is the block size of this pool.
00839     ///
00840     /// The caller of this method must make sure that the \a poolSto pointer
00841     /// is properly aligned. In particular, it must be possible to efficiently
00842     /// store a pointer at the location pointed to by \a poolSto.
00843     /// Internally, the QMPool::init() function rounds up the block size
00844     /// \a blockSize so that it can fit an integer number of pointers.
00845     /// This is done to achieve proper alignment of the blocks within the
00846     /// pool.
00847     ///
00848     /// \note Due to the rounding of block size the actual capacity of the
00849     /// pool might be less than (\a poolSize / \a blockSize). You can check
00850     ///  the capacity of the pool by calling the QF::getPoolMargin() function.
00851     void init(void * const poolSto, uint32_t const poolSize,
00852               QMPoolSize const blockSize);
00853 
00854     /// \brief Obtains a memory block from a memory pool.
00855     ///
00856     /// The only parameter \a me is a pointer to the ::QMPool from which the
00857     /// block is requested. The function returns a pointer to the allocated
00858     /// memory block or NULL if no free blocks are available.
00859     ///
00860     /// A allocated block must be returned to the same pool from which it has
00861     /// been allocated.
00862     ///
00863     /// This function can be called from any task level or ISR level.
00864     ///
00865     /// \note The memory pool \a me must be initialized before any events can
00866     /// be requested from it. Also, the QMPool::get() function uses internally
00867     /// a QF critical section, so you should be careful not to call it from
00868     /// within a critical section when nesting of critical section is not
00869     /// supported.
00870     ///
00871     /// \sa QMPool::put()
00872     void *get(void);
00873 
00874     /// \brief Returns a memory block back to a memory pool.
00875     ///
00876     ///
00877     /// This function can be called from any task level or ISR level.
00878     ///
00879     /// \note The block must be allocated from the same memory pool to which
00880     /// it is returned. The QMPool::put() function raises an assertion if the
00881     /// returned pointer to the block points outside of the original memory
00882     /// buffer managed by the memory pool. Also, the QMPool::put() function
00883     /// uses internally a QF critical section, so you should be careful not
00884     /// to call it from within a critical section when nesting of critical
00885     /// section is not supported.
00886     ///
00887     /// \sa QMPool::get()
00888     void put(void * const b);
00889 
00890     /// \brief return the fixed block-size of the blocks managed by this pool
00891     QMPoolSize getBlockSize(void) const {
00892         return m_blockSize;
00893     }
00894 
00895 private:
00896     friend class QF;
00897 };
00898 
00899 QP_END_
00900 
00901 /// \brief Memory pool element to allocate correctly aligned storage
00902 /// for QMPool class.
00903 ///
00904 #define QF_MPOOL_EL(type_) \
00905     struct { void *sto_[((sizeof(type_) - 1U)/sizeof(void*)) + 1U]; }
00906 
00907 // "qpset.h" =================================================================
00908 /// \brief platform-independent priority sets of 8 or 64 elements.
00909 ///
00910 /// This header file must be included in those QF ports that use the
00911 /// cooperative multitasking QF scheduler or the QK.
00912 
00913 QP_BEGIN_
00914 
00915 //////////////////////////////////////////////////////////////////////////////
00916 // useful lookup tables
00917 
00918 /// \brief Lookup table for (log2(n) + 1), where n is the index
00919 /// into the table.
00920 ///
00921 /// This lookup delivers the 1-based number of the most significant 1-bit
00922 /// of a byte.
00923 ///
00924 /// \note Index range n = 0..255. The first index (n == 0) should never
00925 /// be used.
00926 ///
00927 extern uint8_t const Q_ROM Q_ROM_VAR QF_log2Lkup[256];
00928 
00929 /// \brief Lookup table for (1 << ((n-1) % 8)), where n is the index
00930 /// into the table.
00931 ///
00932 /// \note Index range n = 0..64. The first index (n == 0) should never
00933 /// be used.
00934 extern uint8_t const Q_ROM Q_ROM_VAR QF_pwr2Lkup[65];
00935 
00936 /// \brief Lookup table for ~(1 << ((n-1) % 8)), where n is the index
00937 /// into the table.
00938 ///
00939 /// \note Index range n = 0..64. The first index (n == 0) should never
00940 /// be used.
00941 extern uint8_t const Q_ROM Q_ROM_VAR QF_invPwr2Lkup[65];
00942 
00943 /// \brief Lookup table for (n-1)/8
00944 ///
00945 /// \note Index range n = 0..64. The first index (n == 0) should never
00946 /// be used.
00947 extern uint8_t const Q_ROM Q_ROM_VAR QF_div8Lkup[65];
00948 
00949 
00950 //////////////////////////////////////////////////////////////////////////////
00951 /// \brief Priority Set of up to 8 elements for building various schedulers,
00952 /// but also useful as a general set of up to 8 elements of any kind.
00953 ///
00954 /// The priority set represents the set of active objects that are ready to
00955 /// run and need to be considered by scheduling processing. The set is capable
00956 /// of storing up to 8 priority levels.
00957 class QPSet8 {
00958 
00959     //////////////////////////////////////////////////////////////////////////
00960     /// \brief bimask representing elements of the set
00961     uint8_t m_bits;
00962 
00963 public:
00964 
00965     /// \brief the function evaluates to TRUE if the set is empty,
00966     /// which means that no active objects are ready to run.
00967     bool isEmpty(void) const {
00968         return (m_bits == static_cast<uint8_t>(0));
00969     }
00970 
00971     /// \brief the function evaluates to TRUE if the set has elements,
00972     /// which means that some active objects are ready to run.
00973     bool notEmpty(void) const {
00974         return (m_bits != static_cast<uint8_t>(0));
00975     }
00976 
00977     /// \brief the function evaluates to TRUE if the priority set has the
00978     /// element \a n.
00979     bool hasElement(uint8_t const n) const {
00980         return ((m_bits & Q_ROM_BYTE(QF_pwr2Lkup[n]))
00981                 != static_cast<uint8_t>(0));
00982     }
00983 
00984     /// \brief insert element \a n into the set, n = 1..8
00985     void insert(uint8_t const n) {
00986         m_bits |= Q_ROM_BYTE(QF_pwr2Lkup[n]);
00987     }
00988 
00989     /// \brief remove element \a n from the set, n = 1..8
00990     void remove(uint8_t const n) {
00991         m_bits &= Q_ROM_BYTE(QF_invPwr2Lkup[n]);
00992     }
00993 
00994     /// \brief find the maximum element in the set,
00995     /// \note returns zero if the set is empty
00996     uint8_t findMax(void) const {
00997         return Q_ROM_BYTE(QF_log2Lkup[m_bits]);
00998     }
00999 
01000     friend class QPSet64;
01001 };
01002 
01003 //////////////////////////////////////////////////////////////////////////////
01004 /// \brief Priority Set of up to 64 elements for building various schedulers,
01005 /// but also useful as a general set of up to 64 elements of any kind.
01006 ///
01007 /// The priority set represents the set of active objects that are ready to
01008 /// run and need to be considered by scheduling processing. The set is capable
01009 /// of storing up to 64 priority levels.
01010 ///
01011 /// The priority set allows to build cooperative multitasking schedulers
01012 /// to manage up to 64 tasks. It is also used in the Quantum Kernel (QK)
01013 /// preemptive scheduler.
01014 ///
01015 /// The inherited 8-bit set is used as the 8-elemtn set of of 8-bit subsets
01016 /// Each bit in the super.bits set represents a subset (8-elements)
01017 /// as follows: \n
01018 /// bit 0 in this->m_bits is 1 when subset[0] is not empty \n
01019 /// bit 1 in this->m_bits is 1 when subset[1] is not empty \n
01020 /// bit 2 in this->m_bits is 1 when subset[2] is not empty \n
01021 /// bit 3 in this->m_bits is 1 when subset[3] is not empty \n
01022 /// bit 4 in this->m_bits is 1 when subset[4] is not empty \n
01023 /// bit 5 in this->m_bits is 1 when subset[5] is not empty \n
01024 /// bit 6 in this->m_bits is 1 when subset[6] is not empty \n
01025 /// bit 7 in this->m_bits is 1 when subset[7] is not empty \n
01026 class QPSet64 {
01027 
01028     //////////////////////////////////////////////////////////////////////////
01029     /// \brief bimask representing 8-element subsets of the set
01030     uint8_t m_bytes;
01031 
01032     /// \brief bits representing elements in the set as follows: \n
01033     /// m_bits[0] represent elements  1..8  \n
01034     /// m_bits[1] represent elements  9..16 \n
01035     /// m_bits[2] represent elements 17..24 \n
01036     /// m_bits[3] represent elements 25..32 \n
01037     /// m_bits[4] represent elements 33..40 \n
01038     /// m_bits[5] represent elements 41..48 \n
01039     /// m_bits[6] represent elements 49..56 \n
01040     /// m_bits[7] represent elements 57..64 \n
01041     uint8_t m_bits[8];
01042 
01043 public:
01044 
01045     /// \brief the function evaluates to TRUE if the set is empty,
01046     /// which means that no active objects are ready to run.
01047     bool isEmpty(void) const {
01048         return (m_bytes == static_cast<uint8_t>(0));
01049     }
01050 
01051     /// \brief the function evaluates to TRUE if the set has elements,
01052     /// which means that some active objects are ready to run.
01053     bool notEmpty(void) const {
01054         return (m_bytes != static_cast<uint8_t>(0));
01055     }
01056 
01057     /// \brief the function evaluates to TRUE if the priority set has the
01058     /// element \a n.
01059     bool hasElement(uint8_t const n) const {
01060         uint8_t const m = Q_ROM_BYTE(QF_div8Lkup[n]);
01061         return ((m_bits[m] & Q_ROM_BYTE(QF_pwr2Lkup[n]))
01062                 != static_cast<uint8_t>(0));
01063     }
01064 
01065     /// \brief insert element \a n into the set, n = 1..64
01066     void insert(uint8_t const n) {
01067         uint8_t m = Q_ROM_BYTE(QF_div8Lkup[n]);
01068         m_bits[m] |= Q_ROM_BYTE(QF_pwr2Lkup[n]);
01069         m_bytes |= Q_ROM_BYTE(QF_pwr2Lkup[m + static_cast<uint8_t>(1)]);
01070     }
01071 
01072     /// \brief remove element \a n from the set, n = 1..64
01073     void remove(uint8_t const n) {
01074         uint8_t m = Q_ROM_BYTE(QF_div8Lkup[n]);
01075         if ((m_bits[m] &= Q_ROM_BYTE(QF_invPwr2Lkup[n]))
01076              == static_cast<uint8_t>(0))
01077         {
01078             m_bytes &=Q_ROM_BYTE(QF_invPwr2Lkup[m + static_cast<uint8_t>(1)]);
01079         }
01080     }
01081 
01082     /// \brief find the maximum element in the set,
01083     /// \note returns zero if the set is empty
01084     uint8_t findMax(void) const {
01085         uint8_t n;
01086         if (m_bytes != static_cast<uint8_t>(0)) {
01087             n = static_cast<uint8_t>(Q_ROM_BYTE(QF_log2Lkup[m_bytes])
01088                                      - static_cast<uint8_t>(1));
01089             n = static_cast<uint8_t>(
01090                     Q_ROM_BYTE(QF_log2Lkup[m_bits[n]])
01091                                + static_cast<uint8_t>(n << 3));
01092         }
01093         else {
01094             n = static_cast<uint8_t>(0);
01095         }
01096         return n;
01097     }
01098 };
01099 
01100 QP_END_
01101 
01102 
01103 //////////////////////////////////////////////////////////////////////////////
01104 // Kernel selection based on QK_PREEMPTIVE
01105 //
01106 #ifdef QK_PREEMPTIVE
01107 
01108 // "qk.h" ====================================================================
01109 /// \brief This macro defines the type of the event queue used for the
01110 /// active objects.
01111 ///
01112 /// \note This is just an example of the macro definition. Typically, you need
01113 /// to define it in the specific QF port file (qf_port.h). In case of QK,
01114 /// which always depends on the native QF queue, this macro is defined at the
01115 /// level of the platform-independent interface qk.h.
01116 #define QF_EQUEUE_TYPE             QEQueue
01117 
01118 #if defined(QK_TLS) || defined(QK_EXT_SAVE)
01119     /// \brief This macro defines the type of the OS-Object used for blocking
01120     /// the native QF event queue when the queue is empty
01121     ///
01122     /// In QK, the OS object is used to hold the per-thread flags, which might
01123     /// be used, for example, to rembember the thread attributes (e.g.,
01124     /// if the thread uses a floating point co-processor). The OS object value
01125     /// is set on per-thread basis in QActive::start(). Later, the extended
01126     /// context switch macros (QK_EXT_SAVE() and QK_EXT_RESTORE()) might use
01127     /// the per-thread flags to determine what kind of extended context switch
01128     /// this particular thread needs (e.g., the thread might not be using the
01129     /// coprocessor or might be using a different one).
01130     #define QF_OS_OBJECT_TYPE      uint8_t
01131 
01132     /// \brief This macro defines the type of the thread handle used for the
01133     /// active objects.
01134     ///
01135     /// The thread type in QK is the pointer to the thread-local storage (TLS)
01136     /// This thread-local storage can be set on per-thread basis in
01137     /// QActive::start(). Later, the QK scheduler, passes the pointer to the
01138     /// thread-local storage to the macro #QK_TLS.
01139     #define QF_THREAD_TYPE         void *
01140 #endif                                                // QK_TLS || QK_EXT_SAVE
01141 
01142 #if (QF_MAX_ACTIVE <= 8)
01143     extern "C" QP_ QPSet8  QK_readySet_;                  ///< ready set of QK
01144 #else
01145     extern "C" QP_ QPSet64 QK_readySet_;                  ///< ready set of QK
01146 #endif
01147 
01148 extern "C" uint8_t QK_currPrio_;          ///< current task/interrupt priority
01149 extern "C" uint8_t QK_intNest_;                   ///< interrupt nesting level
01150 
01151 // QK active object queue implementation .....................................
01152 
01153 /// \brief Platform-dependent macro defining how QF should block the calling
01154 /// task when the QF native queue is empty
01155 ///
01156 /// \note This is just an example of #QACTIVE_EQUEUE_WAIT_ for the QK-port
01157 /// of QF. QK never activates a task that has no events to process, so in this
01158 /// case the macro asserts that the queue is not empty. In other QF ports you
01159 // need to define the macro appropriately for the underlying kernel/OS you're
01160 /// using.
01161 #define QACTIVE_EQUEUE_WAIT_(me_) \
01162     Q_ASSERT((me_)->m_eQueue.m_frontEvt != static_cast<QEvt const *>(0))
01163 
01164 /// \brief Platform-dependent macro defining how QF should signal the
01165 /// active object task that an event has just arrived.
01166 ///
01167 /// The macro is necessary only when the native QF event queue is used.
01168 /// The signaling of task involves unblocking the task if it is blocked.
01169 ///
01170 /// \note #QACTIVE_EQUEUE_SIGNAL_ is called from a critical section.
01171 /// It might leave the critical section internally, but must restore
01172 /// the critical section before exiting to the caller.
01173 ///
01174 /// \note This is just an example of #QACTIVE_EQUEUE_SIGNAL_ for the QK-port
01175 /// of QF. In other QF ports you need to define the macro appropriately for
01176 /// the underlying kernel/OS you're using.
01177 #define QACTIVE_EQUEUE_SIGNAL_(me_) do { \
01178     QK_readySet_.insert((me_)->m_prio); \
01179     if (QK_intNest_ == static_cast<uint8_t>(0)) { \
01180         uint8_t p = QK_schedPrio_(); \
01181         if (p != static_cast<uint8_t>(0)) { \
01182             QK_sched_(p); \
01183         } \
01184     } \
01185 } while (false)
01186 
01187 /// \brief Platform-dependent macro defining the action QF should take
01188 /// when the native QF event queue becomes empty.
01189 ///
01190 /// \note #QACTIVE_EQUEUE_ONEMPTY_ is called from a critical section.
01191 /// It should not leave the critical section.
01192 ///
01193 /// \note This is just an example of #QACTIVE_EQUEUE_ONEMPTY_ for the QK-port
01194 /// of QF. In other QF ports you need to define the macro appropriately for
01195 /// the underlying kernel/OS you're using.
01196 #define QACTIVE_EQUEUE_ONEMPTY_(me_) \
01197     QK_readySet_.remove((me_)->m_prio)
01198 
01199 // QK event pool operations ..................................................
01200 
01201 /// \brief This macro defines the type of the event pool used in this QF port.
01202 ///
01203 /// \note This is a specific implementation for the QK-port of QF.
01204 /// In other QF ports you need to define the macro appropriately for
01205 /// the underlying kernel/OS you're using.
01206 #define QF_EPOOL_TYPE_              QMPool
01207 
01208 /// \brief Platform-dependent macro defining the event pool initialization
01209 ///
01210 /// \note This is a specific implementation for the QK-port of QF.
01211 /// In other QF ports you need to define the macro appropriately for
01212 /// the underlying kernel/OS you're using.
01213 #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \
01214     (p_).init((poolSto_), (poolSize_), \
01215         static_cast<QMPoolSize>(evtSize_))
01216 
01217 /// \brief Platform-dependent macro defining how QF should obtain the
01218 /// event pool block-size
01219 ///
01220 /// \note This is a specific implementation for the QK-port of QF.
01221 /// In other QF ports you need to define the macro appropriately for
01222 /// the underlying kernel/OS you're using.
01223 #define QF_EPOOL_EVENT_SIZE_(p_)    \
01224     static_cast<uint32_t>((p_).getBlockSize())
01225 
01226 /// \brief Platform-dependent macro defining how QF should obtain an event
01227 /// \a e_ from the event pool \a p_
01228 ///
01229 /// \note This is a specific implementation for the QK-port of QF.
01230 /// In other QF ports you need to define the macro appropriately for
01231 /// the underlying kernel/OS you're using.
01232 #define QF_EPOOL_GET_(p_, e_)       ((e_) = static_cast<QEvt *>((p_).get()))
01233 
01234 /// \brief Platform-dependent macro defining how QF should return an event
01235 /// \a e_ to the event pool \a p_
01236 ///
01237 /// \note This is a specific implementation for the QK-port of QF.
01238 /// In other QF ports you need to define the macro appropriately for
01239 /// the underlying kernel/OS you're using.
01240 #define QF_EPOOL_PUT_(p_, e_)       ((p_).put(e_))
01241 
01242 //////////////////////////////////////////////////////////////////////////////
01243 QP_BEGIN_
01244 
01245 #ifndef QK_NO_MUTEX
01246     //////////////////////////////////////////////////////////////////////////
01247     /// \brief QK Mutex type.
01248     ///
01249     /// QMutex represents the priority-ceiling mutex available in QK.
01250     /// \sa QK::mutexLock()
01251     /// \sa QK::mutexUnlock()
01252     typedef uint8_t QMutex;
01253 #endif                                                          // QK_NO_MUTEX
01254 
01255 //////////////////////////////////////////////////////////////////////////////
01256 /// \brief QK services.
01257 ///
01258 /// This class groups together QK services. It has only static members and
01259 /// should not be instantiated.
01260 ///
01261 // \note The QK scheduler, QK priority, QK ready set, etc. belong conceptually
01262 /// to the QK class (as static class members). However, to avoid C++ potential
01263 /// name-mangling problems in assembly language, these elements are defined
01264 /// outside of the QK class and use the extern "C" linkage specification.
01265 ///
01266 class QK {
01267 public:
01268 
01269     /// \brief get the current QK version number string
01270     ///
01271     /// \return version of the QK as a constant 6-character string of the
01272     /// form x.y.zz, where x is a 1-digit major version number, y is a
01273     /// 1-digit minor version number, and zz is a 2-digit release number.
01274     static char_t const Q_ROM * Q_ROM_VAR getVersion(void);
01275 
01276     /// \brief QK idle callback (customized in BSPs for QK)
01277     ///
01278     /// QK::onIdle() is called continously by the QK idle loop. This callback
01279     /// gives the application an opportunity to enter a power-saving CPU mode,
01280     /// or perform some other idle processing.
01281     ///
01282     /// \note QK::onIdle() is invoked with interrupts unlocked and must also
01283     /// return with interrupts unlocked.
01284     ///
01285     /// \sa QF::onIdle()
01286     static void onIdle(void);
01287 
01288 #ifndef QK_NO_MUTEX
01289 
01290     /// \brief QK priority-ceiling mutex lock
01291     ///
01292     /// Lock the QK scheduler up to the priority level \a prioCeiling.
01293     ///
01294     // \note This function should be always paired with QK::mutexUnlock().
01295     /// The code between QK::mutexLock() and QK::mutexUnlock() should be
01296     /// kept to the minimum.
01297     ///
01298     /// \include qk_mux.cpp
01299     static QMutex mutexLock(uint8_t const prioCeiling);
01300 
01301     /// \brief QK priority-ceiling mutex unlock
01302     ///
01303     /// \note This function should be always paired with QK::mutexLock().
01304     /// The code between QK::mutexLock() and QK::mutexUnlock() should be
01305     /// kept to the minimum.
01306     ///
01307     /// \include qk_mux.cpp
01308     static void mutexUnlock(QMutex const mutex);
01309 
01310 #endif                                                          // QK_NO_MUTEX
01311 
01312 };
01313 
01314 QP_END_
01315 
01316 //////////////////////////////////////////////////////////////////////////////
01317 extern "C" {
01318 
01319 /// \brief QK initialization
01320 ///
01321 /// QK_init() is called from QF_init() in qk.cpp. This function is
01322 /// defined in the QK ports.
01323 void QK_init(void);
01324 
01325 /// \brief The QK scheduler
01326 ///
01327 /// \note The QK scheduler must be always called with the interrupts
01328 /// disabled and enables interrupts internally.
01329 ///
01330 /// \sa QK_schedPrio_()
01331 void QK_sched_(uint8_t p);
01332 
01333 /// \brief The QK extended scheduler for interrupt context
01334 ///
01335 /// \note The QK extended exscheduler must be always called with the
01336 /// interrupts disabled and enables interrupts internally.
01337 ///
01338 /// \sa QK_schedPrio_()
01339 void QK_schedExt_(uint8_t p);
01340 
01341 /// \brief Find the highest-priority task ready to run
01342 ///
01343 /// \note QK_schedPrio_() must be always called with interrupts disabled
01344 /// and returns with interrupts disabled.
01345 uint8_t QK_schedPrio_(void);
01346 
01347 }                                                                // extern "C"
01348 
01349 #else                                                         // QK_PREEMPTIVE
01350 
01351 // "qvanilla.h" ==============================================================
01352 /// \brief platform-independent interface to the cooperative "vanilla" kernel.
01353 
01354 QP_BEGIN_
01355                               // the event queue type for the "Vanilla" kernel
01356 #define QF_EQUEUE_TYPE     QEQueue
01357                                               // native event queue operations
01358 #define QACTIVE_EQUEUE_WAIT_(me_) \
01359     Q_ASSERT((me_)->m_eQueue.m_frontEvt != static_cast<QEvt const *>(0))
01360 
01361 #define QACTIVE_EQUEUE_SIGNAL_(me_) \
01362     (QF_readySet_.insert((me_)->m_prio))
01363 
01364 #define QACTIVE_EQUEUE_ONEMPTY_(me_) \
01365     (QF_readySet_.remove((me_)->m_prio))
01366 
01367                                             // native QF event pool operations
01368 #define QF_EPOOL_TYPE_           QMPool
01369 #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \
01370     (p_).init((poolSto_), (poolSize_), static_cast<QMPoolSize>(evtSize_))
01371 #define QF_EPOOL_EVENT_SIZE_(p_) \
01372     static_cast<uint32_t>((p_).getBlockSize())
01373 #define QF_EPOOL_GET_(p_, e_)    ((e_) = static_cast<QEvt *>((p_).get()))
01374 #define QF_EPOOL_PUT_(p_, e_)    ((p_).put(e_))
01375 
01376 QP_END_
01377 
01378 #if (QF_MAX_ACTIVE <= 8)
01379     extern "C" QP_ QPSet8  QF_readySet_;      ///< ready set of active objects
01380 #else
01381     extern "C" QP_ QPSet64 QF_readySet_;      ///< ready set of active objects
01382 #endif
01383 
01384 extern "C" uint8_t QF_currPrio_;          ///< current task/interrupt priority
01385 extern "C" uint8_t QF_intNest_;                   ///< interrupt nesting level
01386 
01387 #endif                                                        // QK_PREEMPTIVE
01388 
01389 
01390 // qf.h (QF platform-independent public interface) ===========================
01391 
01392 /// \brief QF/C++ platform-independent public interface.
01393 ///
01394 /// This header file must be included directly or indirectly
01395 /// in all modules (*.cpp files) that use QF/C++.
01396 
01397 //////////////////////////////////////////////////////////////////////////////
01398 #ifdef Q_EVT_CTOR
01399 #include <new>                                            // for placement new
01400 #endif
01401 
01402 //////////////////////////////////////////////////////////////////////////////
01403 // apply defaults for all undefined configuration parameters
01404 //
01405 #ifndef QF_EVENT_SIZ_SIZE
01406     /// \brief Default value of the macro configurable value in qf_port.h
01407     #define QF_EVENT_SIZ_SIZE    2
01408 #endif
01409 
01410 #ifndef QF_MAX_EPOOL
01411     /// \brief Default value of the macro configurable value in qf_port.h
01412     #define QF_MAX_EPOOL         3
01413 #endif
01414 
01415 #ifndef QF_TIMEEVT_CTR_SIZE
01416     /// \brief macro to override the default QTimeEvtCtr size.
01417     /// Valid values 1, 2, or 4; default 2
01418     #define QF_TIMEEVT_CTR_SIZE  2
01419 #endif
01420 
01421 #if (QF_MAX_ACTIVE < 1) || (63 < QF_MAX_ACTIVE)
01422     #error "QF_MAX_ACTIVE not defined or out of range. Valid range is 1..63"
01423 #endif
01424 
01425 #ifndef QF_ACTIVE_SUPER_
01426 
01427     //////////////////////////////////////////////////////////////////////////
01428     /// \brief The macro defining the base class for QActive.
01429     ///
01430     /// By default, the ::QActive class is derived from ::QHsm. However,
01431     /// if the macro QF_ACTIVE_SUPER_ is defined, QActive is derived from
01432     /// QF_ACTIVE_SUPER_.
01433     ///
01434     /// Clients might choose, for example, to define QF_ACTIVE_SUPER_ as QFsm
01435     /// to avoid the 1-2KB overhead of the hierarchical event processor.
01436     ///
01437     /// Clients might also choose to define QF_ACTIVE_SUPER_ as their own
01438     /// completely customized class that has nothing to do with QHsm or QFsm.
01439     /// The QF_ACTIVE_SUPER_ class must provide member functions init() and
01440     /// dispatch(), consistent with the signatures of QHsm and QFsm. But
01441     /// the implementatin of these functions is completely open.
01442     #define QF_ACTIVE_SUPER_  QHsm
01443 
01444     /// \brief The argument of the base class' constructor.
01445     #define QF_ACTIVE_STATE_  QStateHandler
01446 
01447 #endif
01448 
01449 //////////////////////////////////////////////////////////////////////////////
01450 QP_BEGIN_
01451 
01452 //////////////////////////////////////////////////////////////////////////////
01453 #if (QF_EVENT_SIZ_SIZE == 1)
01454 
01455     /// \brief The data type to store the block-size defined based on
01456     /// the macro #QF_EVENT_SIZ_SIZE.
01457     ///
01458     /// The dynamic range of this data type determines the maximum block
01459     /// size that can be managed by the pool.
01460     typedef uint8_t QEvtSize;
01461 #elif (QF_EVENT_SIZ_SIZE == 2)
01462     typedef uint16_t QEvtSize;
01463 #elif (QF_EVENT_SIZ_SIZE == 4)
01464     typedef uint32_t QEvtSize;
01465 #else
01466     #error "QF_EVENT_SIZ_SIZE defined incorrectly, expected 1, 2, or 4"
01467 #endif
01468 
01469 //////////////////////////////////////////////////////////////////////////////
01470 #if (QF_TIMEEVT_CTR_SIZE == 1)
01471     /// \brief type of the Time Event counter, which determines the dynamic
01472     /// range of the time delays measured in clock ticks.
01473     ///
01474     /// This typedef is configurable via the preprocessor switch
01475     /// #QF_TIMEEVT_CTR_SIZE. The other possible values of this type are
01476     /// as follows: \n
01477     /// uint8_t when (QF_TIMEEVT_CTR_SIZE == 1), and \n
01478     /// uint32_t when (QF_TIMEEVT_CTR_SIZE == 4).
01479     typedef uint8_t QTimeEvtCtr;
01480 #elif (QF_TIMEEVT_CTR_SIZE == 2)
01481     typedef uint16_t QTimeEvtCtr;
01482 #elif (QF_TIMEEVT_CTR_SIZE == 4)
01483     typedef uint32_t QTimeEvtCtr;
01484 #else
01485     #error "QF_TIMEEVT_CTR_SIZE defined incorrectly, expected 1, 2, or 4"
01486 #endif
01487 
01488 class QEQueue;                                          // forward declaration
01489 
01490 //////////////////////////////////////////////////////////////////////////////
01491 /// \brief Base class for derivation of application-level active object
01492 /// classes.
01493 ///
01494 /// QActive is the base class for derivation of active objects. Active objects
01495 /// in QF are encapsulated tasks (each embedding a state machine and an event
01496 /// queue) that communicate with one another asynchronously by sending and
01497 /// receiving events. Within an active object, events are processed
01498 /// sequentially in a run-to-completion (RTC) fashion, while QF encapsulates
01499 /// all the details of thread-safe event exchange and queuing.
01500 ///
01501 /// \note QActive is not intended to be instantiated directly, but rather
01502 /// serves as the base class for derivation of active objects in the
01503 /// application code.
01504 ///
01505 /// The following example illustrates how to derive an active object from
01506 /// QActive.
01507 /// \include qf_qactive.cpp
01508 ///
01509 /// \sa #QF_ACTIVE_SUPER_ defines the base class for QActive
01510 class QActive : public QF_ACTIVE_SUPER_ {
01511 
01512 #ifdef QF_EQUEUE_TYPE
01513     /// \brief OS-dependent event-queue type.
01514     ///
01515     /// The type of the queue depends on the underlying operating system or
01516     /// a kernel. Many kernels support "message queues" that can be adapted
01517     /// to deliver QF events to the active object. Alternatively, QF provides
01518     /// a native event queue implementation that can be used as well.
01519     ///
01520     /// The native QF event queue is configured by defining the macro
01521     /// #QF_EQUEUE_TYPE as ::QEQueue.
01522     QF_EQUEUE_TYPE m_eQueue;
01523 #endif
01524 
01525 #ifdef QF_OS_OBJECT_TYPE
01526     /// \brief OS-dependent per-thread object.
01527     ///
01528     /// This data might be used in various ways, depending on the QF port.
01529     /// In some ports m_osObject is used to block the calling thread when
01530     /// the native QF queue is empty. In other QF ports the OS-dependent
01531     /// object might be used differently.
01532     QF_OS_OBJECT_TYPE m_osObject;
01533 #endif
01534 
01535 #ifdef QF_THREAD_TYPE
01536     /// \brief OS-dependent representation of the thread of the active
01537     /// object.
01538     ///
01539     /// This data might be used in various ways, depending on the QF port.
01540     /// In some ports m_thread is used store the thread handle. In other ports
01541     /// m_thread can be a pointer to the Thread-Local-Storage (TLS).
01542     QF_THREAD_TYPE m_thread;
01543 #endif
01544 
01545     /// \brief QF priority associated with the active object.
01546     /// \sa QActive::start()
01547     uint8_t m_prio;
01548 
01549 public:
01550     /// \brief Starts execution of an active object and registers the object
01551     /// with the framework.
01552     ///
01553     /// The function takes six arguments.
01554     /// \a prio is the priority of the active object. QF allows you to start
01555     /// up to 63 active objects, each one having a unique priority number
01556     /// between 1 and 63 inclusive, where higher numerical values correspond
01557     /// to higher priority (urgency) of the active object relative to the
01558     /// others.
01559     /// \a qSto[] and \a qLen arguments are the storage and size of the event
01560     /// queue used by this active object.
01561     /// \a stkSto and \a stkSize are the stack storage and size in bytes.
01562     /// Please note that a per-active object stack is used only when the
01563     /// underlying OS requies it. If the stack is not required, or the
01564     /// underlying OS allocates the stack internally, the \a stkSto should be
01565     /// NULL and/or \a stkSize should be 0.
01566     /// \a ie is an optional initialization event that can be used to pass
01567     /// additional startup data to the active object. (Pass NULL if your
01568     /// active object does not expect the initialization event).
01569     ///
01570     /// \note This function is strongly OS-dependent and must be defined in
01571     /// the QF port to a particular platform.
01572     ///
01573     /// The following example shows starting of the Philosopher object when a
01574     /// per-task stack is required:
01575     /// \include qf_start.cpp
01576     void start(uint8_t const prio,
01577                QEvt const *qSto[], uint32_t const qLen,
01578                void * const stkSto, uint32_t const stkSize,
01579                QEvt const * const ie = static_cast<QEvt *>(0));
01580 
01581     /// \brief Posts an event \a e directly to the event queue of the acitve
01582     /// object \a me using the First-In-First-Out (FIFO) policy.
01583     ///
01584     /// Direct event posting is the simplest asynchronous communication method
01585     /// available in QF. The following example illustrates how the Philosopher
01586     /// active obejct posts directly the HUNGRY event to the Table active
01587     /// object. \include qf_post.cpp
01588     ///
01589     /// \note The producer of the event (Philosopher in this case) must only
01590     /// "know" the recipient (Table) by a generic (QActive *QDPP_table)
01591     /// pointer, but the specific definition of the Table class is not
01592     /// required.
01593     ///
01594     /// \note Direct event posting should not be confused with direct event
01595     /// dispatching. In contrast to asynchronous event posting through event
01596     /// queues, direct event dispatching is synchronous. Direct event
01597     /// dispatching occurs when you call QHsm::dispatch(), or QFsm::dispatch()
01598     /// function.
01599 #ifndef Q_SPY
01600     void postFIFO(QEvt const * const e);
01601 #else
01602     void postFIFO(QEvt const * const e, void const * const sender);
01603 #endif
01604 
01605     /// \brief Un-subscribes from the delivery of all signals to the active
01606     /// object.
01607     ///
01608     /// This function is part of the Publish-Subscribe event delivery
01609     /// mechanism available in QF. Un-subscribing from all events means that
01610     /// the framework will stop posting any published events to the event
01611     /// queue of the active object.
01612     ///
01613     /// \note Due to the latency of event queues, an active object should NOT
01614     /// assume that no events will ever be dispatched to the state machine of
01615     /// the active object after un-subscribing from all events.
01616     /// The events might be already in the queue, or just about to be posted
01617     /// and the un-subscribe operation will not flush such events. Also, the
01618     /// alternative event-delivery mechanisms, such as direct event posting or
01619     /// time events, can be still delivered to the event queue of the active
01620     /// object.
01621     ///
01622     /// \sa QF::publish(), QActive::subscribe(), and QActive::unsubscribe()
01623     void unsubscribeAll(void) const;
01624 
01625 protected:
01626     /// \brief protected constructor
01627     ///
01628     /// Performs the first step of active object initialization by assigning
01629     /// the initial pseudostate to the currently active state of the state
01630     /// machine.
01631     ///
01632     /// \note The constructor is protected to prevent direct instantiation
01633     /// of QActive objects. This class is intended only for derivation
01634     /// (abstract class).
01635     QActive(QF_ACTIVE_STATE_ const initial) : QF_ACTIVE_SUPER_(initial) {
01636     }
01637 
01638     /// \brief Posts an event directly to the event queue of the active object
01639     /// \a me using the Last-In-First-Out (LIFO) policy.
01640     ///
01641     /// \note The LIFO policy should be used only for self-posting and with
01642     /// great caution because it alters order of events in the queue.
01643     ///
01644     /// \sa QActive::postFIFO()
01645     void postLIFO(QEvt const * const e);
01646 
01647     /// \brief Stops execution of an active object and removes it from the
01648     /// framework's supervision.
01649     ///
01650     /// The preferred way of calling this function is from within the active
01651     /// object that needs to stop (that's why this function is protected).
01652     /// In other words, an active object should stop itself rather than being
01653     /// stopped by some other entity. This policy works best, because only
01654     /// the active object itself "knows" when it has reached the appropriate
01655     /// state for the shutdown.
01656     ///
01657     /// \note This function is strongly OS-dependent and should be defined in
01658     /// the QF port to a particular platform. This function is optional in
01659     /// embedded systems where active objects never need to be stopped.
01660     void stop(void);
01661 
01662     /// \brief Subscribes for delivery of signal \a sig to the active object
01663     ///
01664     /// This function is part of the Publish-Subscribe event delivery
01665     /// mechanism available in QF. Subscribing to an event means that the
01666     /// framework will start posting all published events with a given signal
01667     /// \a sig to the event queue of the active object.
01668     ///
01669     /// The following example shows how the Table active object subscribes
01670     /// to three signals in the initial transition:
01671     /// \include qf_subscribe.cpp
01672     ///
01673     /// \sa QF::publish(), QActive::unsubscribe(), and
01674     /// QActive::unsubscribeAll()
01675     void subscribe(enum_t const sig) const;
01676 
01677     /// \brief Un-subscribes from the delivery of signal \a sig to the
01678     /// active object.
01679     ///
01680     /// This function is part of the Publish-Subscribe event delivery
01681     /// mechanism available in QF. Un-subscribing from an event means that
01682     /// the framework will stop posting published events with a given signal
01683     /// \a sig to the event queue of the active object.
01684     ///
01685     /// \note Due to the latency of event queues, an active object should NOT
01686     /// assume that a given signal \a sig will never be dispatched to the
01687     /// state machine of the active object after un-subscribing from that
01688     /// signal. The event might be already in the queue, or just about to be
01689     /// posted and the un-subscribe operation will not flush such events.
01690     ///
01691     /// \note Un-subscribing from a signal that has never been subscribed in
01692     /// the first place is considered an error and QF will rise an assertion.
01693     ///
01694     /// \sa QF::publish(), QActive::subscribe(), and QActive::unsubscribeAll()
01695     void unsubscribe(enum_t const sig) const;
01696 
01697     /// \brief Defer an event to a given separate event queue.
01698     ///
01699     /// This function is part of the event deferral support. An active object
01700     /// uses this function to defer an event \a e to the QF-supported native
01701     /// event queue \a eq. QF correctly accounts for another outstanding
01702     /// reference to the event and will not recycle the event at the end of
01703     /// the RTC step. Later, the active object might recall one event at a
01704     /// time from the event queue.
01705     ///
01706     /// An active object can use multiple event queues to defer events of
01707     /// different kinds.
01708     ///
01709     /// \sa QActive::recall(), QEQueue
01710     void defer(QEQueue * const eq, QEvt const * const e) const;
01711 
01712     /// \brief Recall a deferred event from a given event queue.
01713     ///
01714     /// This function is part of the event deferral support. An active object
01715     /// uses this function to recall a deferred event from a given QF
01716     /// event queue. Recalling an event means that it is removed from the
01717     /// deferred event queue \a eq and posted (LIFO) to the event queue of
01718     /// the active object.
01719     ///
01720     /// QActive::recall() returns true if an event has been recalled.
01721     /// Otherwise the function returns false.
01722     ///
01723     /// An active object can use multiple event queues to defer events of
01724     /// different kinds.
01725     ///
01726     /// \sa QActive::defer(), QEQueue, QActive::postLIFO()
01727     bool recall(QEQueue * const eq);
01728 
01729 private:
01730 
01731     /// \brief Get an event from the event queue of an active object.
01732     ///
01733     /// This function is used internally by a QF port to extract events from
01734     /// the event queue of an active object. This function depends on the
01735     /// event queue implementation and is sometimes implemented in the QF port
01736     /// (qf_port.cpp file). Depending on the underlying OS or kernel, the
01737     /// function might block the calling thread when no events are available.
01738     ///
01739     /// \note QActive::get_() is public because it often needs to be called
01740     /// from thread-run routines with difficult to foresee signature (so
01741     /// declaring friendship with such function(s) is not possible.)
01742     ///
01743     /// \sa QActive::postFIFO(), QActive::postLIFO()
01744     QEvt const *get_(void);
01745 
01746     friend class QF;
01747     friend class QTimeEvt;
01748 
01749 #ifdef QK_PREEMPTIVE                                       // is this QK port?
01750     friend void ::QK_schedExt_(uint8_t p);
01751     friend void ::QK_sched_(uint8_t p);
01752 #endif
01753 
01754 };
01755 
01756 //////////////////////////////////////////////////////////////////////////////
01757 /// \brief Time Event class
01758 ///
01759 /// Time events are special QF events equipped with the notion of time
01760 /// passage. The basic usage model of the time events is as follows. An
01761 /// active object allocates one or more QTimeEvt objects (provides the
01762 /// storage for them). When the active object needs to arrange for a timeout,
01763 /// it arms one of its time events to fire either just once (one-shot) or
01764 /// periodically. Each time event times out independently from the others,
01765 /// so a QF application can make multiple parallel timeout requests (from the
01766 /// same or different active objects). When QF detects that the appropriate
01767 /// moment has arrived, it inserts the time event directly into the
01768 /// recipient's event queue. The recipient then processes the time event just
01769 /// like any other event.
01770 ///
01771 /// Time events, as any other QF events derive from the ::QEvt base
01772 /// class. Typically, you will use a time event as-is, but you can also
01773 /// further derive more specialized time events from it by adding some more
01774 /// data members and/or specialized functions that operate on the specialized
01775 /// time events.
01776 ///
01777 /// Internally, the armed time events are organized into a bi-directional
01778 /// linked list. This linked list is scanned in every invocation of the
01779 /// QF::tick() function. Only armed (timing out) time events are in the list,
01780 /// so only armed time events consume CPU cycles.
01781 ///
01782 /// \note QF manages the time events in the function QF::tick(), which
01783 /// must be called periodically, preferably from the clock tick ISR.
01784 /// \note In this version of QF QTimeEvt objects should be allocated
01785 /// statically rather than dynamically from event pools. Currently, QF will
01786 /// not correctly recycle the dynamically allocated Time Events.
01787 class QTimeEvt : public QEvt {
01788 private:
01789 
01790     /// link to the next time event in the list
01791     QTimeEvt *m_next;
01792 
01793     /// the active object that receives the time events.
01794     QActive *m_act;
01795 
01796     /// the internal down-counter of the time event. The down-counter
01797     /// is decremented by 1 in every QF_tick() invocation. The time event
01798     /// fires (gets posted or published) when the down-counter reaches zero.
01799     QTimeEvtCtr m_ctr;
01800 
01801     /// the interval for the periodic time event (zero for the one-shot
01802     /// time event). The value of the interval is re-loaded to the internal
01803     /// down-counter when the time event expires, so that the time event
01804     /// keeps timing out periodically.
01805     QTimeEvtCtr m_interval;
01806 
01807 public:
01808 
01809     /// \brief The Time Event constructor.
01810     ///
01811     /// The most important initialization performed in  the constructor is
01812     /// assigning a signal to the Time Event. You can reuse the Time Event
01813     /// any number of times, but you cannot change the signal.
01814     /// This is because pointers to Time Events might still be held in event
01815     /// queues and changing signal could to hard-to-detect errors.
01816     ///
01817     /// The following example shows the use of QTimeEvt::QTimeEvt()
01818     /// constructor in the constructor initializer list of the Philosopher
01819     /// active object constructor that owns the time event
01820     /// \include qf_ctor.cpp
01821     QTimeEvt(enum_t const s);
01822 
01823     /// \brief Arm a one-shot time event for direct event posting.
01824     ///
01825     /// Arms a time event to fire in \a nTicks clock ticks (one-shot time
01826     /// event). The time event gets directly posted (using the FIFO policy)
01827     /// into the event queue of the active object \a act.
01828     ///
01829     /// After posting, the time event gets automatically disarmed and can be
01830     /// reused for a one-shot or periodic timeout requests.
01831     ///
01832     /// A one-shot time event can be disarmed at any time by calling the
01833     /// QTimeEvt::disarm() function. Also, a one-shot time event can be
01834     /// re-armed to fire in a different number of clock ticks by calling the
01835     /// QTimeEvt::rearm() function.
01836     ///
01837     /// The following example shows how to arm a one-shot time event from a
01838     /// state machine of an active object:
01839     /// \include qf_state.cpp
01840     void postIn(QActive * const act, QTimeEvtCtr const nTicks) {
01841         m_interval = static_cast<QTimeEvtCtr>(0);
01842         arm_(act, nTicks);
01843     }
01844 
01845     /// \brief Arm a periodic time event for direct event posting.
01846     ///
01847     /// Arms a time event to fire every \a nTicks clock ticks (periodic time
01848     /// event). The time event gets directly posted (using the FIFO policy)
01849     /// into the event queue of the active object \a act.
01850     ///
01851     /// After posting, the time event gets automatically re-armed to fire
01852     /// again in the specified \a nTicks clock ticks.
01853     ///
01854     /// A periodic time event can be disarmed only by calling the
01855     /// QTimeEvt::disarm() function. After disarming, the time event can be
01856     /// reused for a one-shot or periodic timeout requests.
01857     ///
01858     /// \note An attempt to reuse (arm again) a running periodic time event
01859     /// raises an assertion.
01860     ///
01861     /// Also, a periodic time event can be re-armed to shorten or extend the
01862     /// current period by calling the QTimeEvt_rearm() function. After
01863     /// adjusting the current period, the periodic time event goes back
01864     /// timing out at the original rate.
01865     void postEvery(QActive * const act, QTimeEvtCtr const nTicks) {
01866         m_interval = nTicks;
01867         arm_(act, nTicks);
01868     }
01869 
01870     /// \brief Disarm a time event.
01871     ///
01872     /// The time event gets disarmed and can be reused. The function
01873     /// returns true if the time event was truly disarmed, that is, it
01874     /// was running. The return of false means that the time event was
01875     /// not truly disarmed because it was not running. The 'false' return is
01876     /// only possible for one-shot time events that have been automatically
01877     /// disarmed upon expiration. In this case the 'false' return means that
01878     /// the time event has already been posted or published and should be
01879     /// expected in the active object's state machine.
01880     bool disarm(void);
01881 
01882     /// \brief Rearm a time event.
01883     ///
01884     /// The time event gets rearmed with a new number of clock ticks
01885     /// \a nTicks. This facility can be used to prevent a one-shot time event
01886     /// from expiring (e.g., a watchdog time event), or to adjusts the
01887     /// current period of a periodic time event. Rearming a periodic timer
01888     /// leaves the interval unchanged and is a convenient method to adjust
01889     /// the phasing of the periodic time event.
01890     ///
01891     /// The function returns true if the time event was running as it
01892     /// was re-armed. The return of false means that the time event was
01893     /// not truly rearmed because it was not running. The 'false' return is
01894     /// only possible for one-shot time events that have been automatically
01895     /// disarmed upon expiration. In this case the 'false' return means that
01896     /// the time event has already been posted or published and should be
01897     /// expected in the active object's state machine.
01898     bool rearm(QTimeEvtCtr const nTicks);
01899 
01900     /// \brief Get the current value of the down-counter of a time event.
01901     ///
01902     /// If the time event is armed, the function returns the current value of
01903     /// the down-counter of the given time event. If the time event is not
01904     /// armed, the function returns 0.
01905     ///
01906     /// /note The function is thread-safe.
01907     QTimeEvtCtr ctr(void) const;
01908 
01909 private:
01910 
01911     /// \brief Arm a time event (internal function to be used through macros
01912     /// only).
01913     ///
01914     /// \sa QTimeEvt::postIn(), QTimeEvt::postEvery(),
01915     /// \sa QTimeEvt::publishIn(), QTimeEvt::publishEvery()
01916     void arm_(QActive * const act, QTimeEvtCtr const nTicks);
01917 
01918     friend class QF;
01919 };
01920 
01921 
01922 //////////////////////////////////////////////////////////////////////////////
01923 /// \brief The size of the Subscriber list bit array
01924 ///
01925 /// The size is determined of the maximum number of active objects in the
01926 /// application configured by the #QF_MAX_ACTIVE macro.
01927 uint8_t const QF_SUBSCR_LIST_SIZE =
01928     static_cast<uint8_t>(((QF_MAX_ACTIVE - 1) / 8) + 1);
01929 
01930 /// \brief Subscriber List class
01931 ///
01932 /// This data type represents a set of active objects that subscribe to
01933 /// a given signal. The set is represented as an array of bits, where each
01934 /// bit corresponds to the unique priority of an active object.
01935 class QSubscrList {
01936 private:
01937 
01938     /// An array of bits representing subscriber active objects. Each bit
01939     /// in the array corresponds to the unique priority of the active object.
01940     /// The size of the array is determined of the maximum number of active
01941     /// objects in the application configured by the #QF_MAX_ACTIVE macro.
01942     /// For example, an active object of priority p is a subscriber if the
01943     /// following is true: ((m_bits[QF_div8Lkup[p]] & QF_pwr2Lkup[p]) != 0)
01944     ///
01945     /// \sa QF::psInit(), QF_div8Lkup, QF_pwr2Lkup, #QF_MAX_ACTIVE
01946     uint8_t m_bits[QF_SUBSCR_LIST_SIZE];
01947 
01948     friend class QF;
01949     friend class QActive;
01950 };
01951 
01952 //////////////////////////////////////////////////////////////////////////////
01953 /// \brief QF services.
01954 ///
01955 /// This class groups together QF services. It has only static members and
01956 /// should not be instantiated.
01957 class QF {
01958 public:
01959 
01960     /// \brief QF initialization.
01961     ///
01962     /// This function initializes QF and must be called exactly once before
01963     /// any other QF function.
01964     static void init(void);
01965 
01966     /// \brief Publish-subscribe initialization.
01967     ///
01968     /// This function initializes the publish-subscribe facilities of QF and
01969     /// must be called exactly once before any subscriptions/publications
01970     /// occur in the application. The arguments are as follows: \a subscrSto
01971     /// is a pointer to the array of subscriber-lists. \a maxSignal is the
01972     /// dimension of this array and at the same time the maximum signal that
01973     /// can be published or subscribed.
01974     ///
01975     /// The array of subscriber-lists is indexed by signals and provides
01976     /// mapping between the signals and subscirber-lists. The subscriber-
01977     /// lists are bitmasks of type ::QSubscrList, each bit in the bitmask
01978     /// corresponding to the unique priority of an active object. The size
01979     /// of the ::QSubscrList bitmask depends on the value of the
01980     /// #QF_MAX_ACTIVE macro.
01981     ///
01982     /// \note The publish-subscribe facilities are optional, meaning that
01983     /// you might choose not to use publish-subscribe. In that case calling
01984     /// QF::psInit() and using up memory for the subscriber-lists is
01985     /// unnecessary.
01986     ///
01987     /// \sa ::QSubscrList
01988     ///
01989     /// The following example shows the typical initialization sequence of
01990     /// QF: \include qf_main.cpp
01991     static void psInit(QSubscrList * const subscrSto,
01992                        uint32_t const maxSignal);
01993 
01994     /// \brief Event pool initialization for dynamic allocation of events.
01995     ///
01996     /// This function initializes one event pool at a time and must be called
01997     /// exactly once for each event pool before the pool can be used.
01998     /// The arguments are as follows: \a poolSto is a pointer to the memory
01999     /// block for the events. \a poolSize is the size of the memory block in
02000     /// bytes. \a evtSize is the block-size of the pool in bytes, which
02001     /// determines the maximum size of events that can be allocated from the
02002     /// pool.
02003     ///
02004     /// You might initialize one, two, and up to three event pools by making
02005     /// one, two, or three calls to the QF_poolInit() function. However,
02006     /// for the simplicity of the internal implementation, you must initialize
02007     /// event pools in the ascending order of the event size.
02008     ///
02009     /// Many RTOSes provide fixed block-size heaps, a.k.a. memory pools that
02010     /// can be used for QF event pools. In case such support is missing, QF
02011     /// provides a native QF event pool implementation. The macro
02012     /// #QF_EPOOL_TYPE_ determines the type of event pool used by a
02013     /// particular QF port. See class ::QMPool for more information.
02014     ///
02015     /// \note The actual number of events available in the pool might be
02016     /// actually less than (\a poolSize / \a evtSize) due to the internal
02017     /// alignment of the blocks that the pool might perform. You can always
02018     /// check the capacity of the pool by calling QF::getPoolMargin().
02019     ///
02020     /// \note The dynamic allocation of events is optional, meaning that you
02021     /// might choose not to use dynamic events. In that case calling
02022     /// QF::poolInit() and using up memory for the memory blocks is
02023     /// unnecessary.
02024     ///
02025     /// \sa QF initialization example for QF::init()
02026     static void poolInit(void * const poolSto, uint32_t const poolSize,
02027                          uint32_t const evtSize);
02028 
02029     /// \brief Transfers control to QF to run the application.
02030     ///
02031     /// QF::run() is typically called from your startup code after you
02032     /// initialize the QF and start at least one active object with
02033     /// QActive::start(). Also, QF::start() call must precede the transfer
02034     /// of control to QF::run(), but some QF ports might call QF::start()
02035     /// from QF::run(). QF::run() typically never returns to the caller,
02036     /// but when it does, it returns the error code (0 for success)
02037     ///
02038     /// \note This function is strongly platform-dependent and is not
02039     /// implemented in the QF, but either in the QF port or in the
02040     /// Board Support Package (BSP) for the given application. All QF ports
02041     /// must implement QF::run().
02042     ///
02043     /// \note When the Quantum Kernel (QK) is used as the underlying real-time
02044     /// kernel for the QF, all platfrom dependencies are handled in the QK, so
02045     /// no porting of QF is necessary. In other words, you only need to
02046     /// recompile the QF platform-independent code with the compiler for your
02047     /// platform, but you don't need to provide any platform-specific
02048     /// implementation (so, no qf_port.cpp file is necessary). Moreover, QK
02049     /// implements the function QF::run() in a platform-independent way,
02050     /// in the modile qk.cpp.
02051     static int16_t run(void);
02052 
02053     /// \brief Startup QF callback.
02054     ///
02055     /// The timeline for calling QF::onStartup() depends on the particular
02056     /// QF port. In most cases, QF::onStartup() is called from QF::run(),
02057     /// right before starting any multitasking kernel or the background loop.
02058     static void onStartup(void);
02059 
02060     /// \brief Cleanup QF callback.
02061     ///
02062     /// QF::onCleanup() is called in some QF ports before QF returns to the
02063     /// underlying operating system or RTOS.
02064     ///
02065     /// This function is strongly platform-specific and is not implemented in
02066     /// the QF but either in the QF port or in the Board Support Package (BSP)
02067     /// for the given application. Some QF ports might not require
02068     /// implementing QF::onCleanup() at all, because many embedded
02069     /// applications don't have anything to exit to.
02070     ///
02071     /// \sa QF::init() and QF::stop()
02072     static void onCleanup(void);
02073 
02074     /// \brief QF idle callback (customized in BSPs for QF)
02075     ///
02076     /// QF::onIdle() is called by the non-preemptive "Vanilla" scheduler built
02077     /// into QF when the framework detects that no events are available for
02078     /// active objects (the idle condition). This callback gives the
02079     /// application an opportunity to enter a power-saving CPU mode, or
02080     /// perform some other idle processing (such as Q-Spy output).
02081     ///
02082     /// \note QF_onIdle() is invoked with interrupts DISABLED because the idle
02083     /// condition can be asynchronously changed at any time by an interrupt.
02084     /// QF_onIdle() MUST enable the interrupts internally, but not before
02085     /// putting the CPU into the low-power mode. (Ideally, enabling interrupts
02086     /// and low-power mode should happen atomically). At the very least, the
02087     /// function MUST enable interrupts, otherwise interrups will remain
02088     /// disabled permanently.
02089     ///
02090     /// \note QF::onIdle() is only used by the non-preemptive "Vanilla"
02091     /// scheduler in the "bare metal" QF port, and is NOT used in any other
02092     /// QF ports. When QF is combined with QK, the QK idle loop calls a
02093     /// different function QK::onIdle(), with different semantics than
02094     /// QF::onIdle(). When QF is combined with a 3rd-party RTOS or kernel, the
02095     /// idle processing mechanism of the RTOS or kernal is used instead of
02096     /// QF::onIdle().
02097     ///
02098     static void onIdle(void);
02099 
02100     /// \brief Function invoked by the application layer to stop the QF
02101     /// application and return control to the OS/Kernel.
02102     ///
02103     /// This function stops the QF application. After calling this function,
02104     /// QF attempts to gracefully stop the  application. This graceful
02105     /// shutdown might take some time to complete. The typical use of this
02106     /// funcition is for terminating the QF application to return back to the
02107     /// operating system or for handling fatal errors that require shutting
02108     /// down (and possibly re-setting) the system.
02109     ///
02110     /// This function is strongly platform-specific and is not implemented in
02111     /// the QF but either in the QF port or in the Board Support Package (BSP)
02112     /// for the given application. Some QF ports might not require
02113     /// implementing QF::stop() at all, because many embedded application
02114     /// don't have anything to exit to.
02115     ///
02116     /// \sa QF::stop() and QF::onCleanup()
02117     static void stop(void);
02118 
02119     /// \brief Publish event to the framework.
02120     ///
02121     /// This function posts (using the FIFO policy) the event \a e it to ALL
02122     /// active object that have subscribed to the signal \a e->sig.
02123     /// This function is designed to be callable from any part of the system,
02124     /// including ISRs, device drivers, and active objects.
02125     ///
02126     /// In the general case, event publishing requires multi-casting the
02127     /// event to multiple subscribers. This happens in the caller's thread
02128     /// with the scheduler locked to prevent preemptions during the multi-
02129     /// casting process. (Please note that the interrupts are not locked.)
02130 #ifndef Q_SPY
02131     static void publish(QEvt const *e);
02132 #else
02133     static void publish(QEvt const *e, void const *sender);
02134 #endif
02135 
02136     /// \brief Processes all armed time events at every clock tick.
02137     ///
02138     /// This function must be called periodically from a time-tick ISR or from
02139     /// the highest-priority task so that QF can manage the timeout events.
02140     ///
02141     /// \note The QF::tick() function is not reentrant meaning that it must
02142     /// run to completion before it is called again. Also, QF::tick() assumes
02143     /// that it never will get preempted by a task, which is always the case
02144     /// when it is called from an ISR or the highest-priority task.
02145     ///
02146     /// \sa ::QTimeEvt.
02147     ///
02148     /// The following example illustrates the call to QF::tick():
02149     /// \include qf_tick.cpp
02150 #ifndef Q_SPY
02151     static void tick(void);
02152 #else
02153     static void tick(void const * const sender);
02154 #endif
02155 
02156     /// \brief Returns true if all time events are inactive and false
02157     /// any time event is active.
02158     ///
02159     /// \note This function should be called in critical section.
02160     static bool noTimeEvtsActive(void);
02161 
02162     /// \brief Returns the QF version.
02163     ///
02164     /// This function returns constant version string in the format x.y.zz,
02165     /// where x (one digit) is the major version, y (one digit) is the minor
02166     /// version, and zz (two digits) is the maintenance release version.
02167     /// An example of the version string is "3.1.03".
02168     ///
02169     /// The following example illustrates the usage of this function:
02170     /// \include qf_version.cpp
02171     static char_t const Q_ROM * Q_ROM_VAR getVersion(void);
02172 
02173     /// \brief This function returns the margin of the given event pool.
02174     ///
02175     /// This function returns the margin of the given event pool \a poolId,
02176     /// where poolId is the ID of the pool initialized by the call to
02177     /// QF::poolInit(). The poolId of the first initialized pool is 1, the
02178     /// second 2, and so on.
02179     ///
02180     /// The returned pool margin is the minimal number of free blocks
02181     /// encountered in the given pool since system startup.
02182     ///
02183     /// \note Requesting the margin of an un-initialized pool raises an
02184     /// assertion in the QF.
02185     static uint32_t getPoolMargin(uint8_t const poolId);
02186 
02187     /// \brief This function returns the margin of the given event queue.
02188     ///
02189     /// This function returns the margin of the given event queue of an active
02190     /// object with priority \a prio. (QF priorities start with 1 and go up to
02191     /// #QF_MAX_ACTIVE.) The margin is the minimal number of free events
02192     /// encountered in the given queue since system startup.
02193     ///
02194     /// \note QF::getQueueMargin() is available only when the native QF event
02195     /// queue implementation is used. Requesting the queue margin of an unused
02196     /// priority level raises an assertion in the QF. (A priority level
02197     /// becomes used in QF after the call to the QF::add_() function.)
02198     static uint32_t getQueueMargin(uint8_t const prio);
02199 
02200     /// \brief Internal QF implementation of the dynamic event allocator.
02201     ///
02202     /// \note The application code should not call this function directly.
02203     /// Please use the macro #Q_NEW.
02204     static QEvt *new_(QEvtSize const evtSize, enum_t const sig);
02205 
02206     /// \brief Recycle a dynamic event.
02207     ///
02208     /// This function implements a simple garbage collector for the dynamic
02209     /// events. Only dynamic events are candidates for recycling. (A dynamic
02210     /// event is one that is allocated from an event pool, which is
02211     /// determined as non-zero e->attrQF__ attribute.) Next, the function
02212     /// decrements the reference counter of the event, and recycles the event
02213     /// only if the counter drops to zero (meaning that no more references
02214     /// are outstanding for this event). The dynamic event is recycled by
02215     /// returning it to the pool from which it was originally allocated.
02216     /// The pool-of-origin information is stored in the upper 2-MSBs of the
02217     /// e->attrQF__ attribute.)
02218     ///
02219     /// \note QF invokes the garbage collector at all appropriate contexts,
02220     /// when an event can become garbage (automatic garbage collection),
02221     /// so the application code should have NO need to call QF::gc() directly.
02222     /// The QF::gc() function is exposed only for special cases when your
02223     /// application sends dynamic events to the "raw" thread-safe queues
02224     /// (see ::QEQueue). Such queues are processed outside of QF and the
02225     /// automatic garbage collection CANNOT be performed for these events.
02226     /// In this case you need to call QF::gc() explicitly.
02227     static void gc(QEvt const *e);
02228 
02229 private:                              // functions to be used in QF ports only
02230 
02231     /// \brief Register an active object to be managed by the framework
02232     ///
02233     /// This function should not be called by the application directly, only
02234     /// through the function QActive::start(). The priority of the active
02235     /// object \a a should be set before calling this function.
02236     ///
02237     /// \note This function raises an assertion if the priority of the active
02238     /// object exceeds the maximum value #QF_MAX_ACTIVE. Also, this function
02239     /// raises an assertion if the priority of the active object is already in
02240     /// use. (QF requires each active object to have a UNIQUE priority.)
02241     static void add_(QActive * const a);
02242 
02243 public:
02244     /// \brief Remove the active object from the framework.
02245     ///
02246     /// This function should not be called by the application directly, only
02247     /// inside the QF port. The priority level occupied by the active object
02248     /// is freed-up and can be reused for another active object.
02249     ///
02250     /// The active object that is removed from the framework can no longer
02251     /// participate in the publish-subscribe event exchange.
02252     ///
02253     /// \note This function raises an assertion if the priority of the active
02254     /// object exceeds the maximum value #QF_MAX_ACTIVE or is not used.
02255     static void remove_(QActive const * const a);
02256 
02257     /// \brief array of registered active objects
02258     ///
02259     /// \note Not to be used by Clients directly, only in ports of QF
02260     static QActive *active_[];
02261 
02262     /// \brief Thread routine for executing an active object \a act.
02263     ///
02264     /// This function is actually implemented internally by certain QF ports
02265     /// to be called by the active object thread routine.
02266     static void thread_(QActive *act);
02267 
02268     friend class QActive;
02269 };
02270 
02271 QP_END_
02272 
02273 //////////////////////////////////////////////////////////////////////////////
02274 #ifdef Q_EVT_CTOR               // Provide the constructor for the QEvt class?
02275 
02276     /// \brief Allocate a dynamic event.
02277     ///
02278     /// This macro returns an event pointer cast to the type \a evtT_. The
02279     /// event is initialized with the signal \a sig. Internally, the macro
02280     /// calls the internal QF function QF::new_(), which always returns a
02281     /// valid event pointer.
02282     ///
02283     /// \note The internal QF function QF::new_() raises an assertion when
02284     /// the allocation of the event turns out to be impossible due to
02285     /// event pool depletion, or incorrect (too big) size of the requested
02286     /// event.
02287     ///
02288     /// The following example illustrates dynamic allocation of an event:
02289     /// \include qf_post.cpp
02290     #define Q_NEW(evtT_, sig_, ...) \
02291         (new(QP_ QF::new_( \
02292             static_cast<QP_ QEvtSize>(sizeof(evtT_)), (sig_))) \
02293             evtT_((sig_),  ##__VA_ARGS__))
02294 #else                                    // QEvt is a POD (Plain Old Datatype)
02295 
02296     #define Q_NEW(evtT_, sig_) \
02297         (static_cast<evtT_ *>( \
02298             QP_ QF::new_(static_cast<QP_ QEvtSize>(sizeof(evtT_)), (sig_))))
02299 #endif
02300 
02301 //////////////////////////////////////////////////////////////////////////////
02302 // QS software tracing integration, only if enabled
02303 #ifdef Q_SPY                                   // QS software tracing enabled?
02304 
02305     /// \brief Invoke the system clock tick processing QF::tick(). This macro
02306     /// is the recommended way of invoking clock tick processing, because it
02307     /// provides the vital information for software tracing and avoids any
02308     /// overhead when the tracing is disabled.
02309     ///
02310     /// This macro takes the argument \a sender_, which is a pointer to the
02311     /// sender object. This argument is actually only used when QS software
02312     /// tracing is enabled (macro #Q_SPY is defined). When QS software
02313     /// tracing is disabled, the macro calls QF::tick() without any
02314     /// arguments, so the overhead of passing this extra argument is
02315     /// entirely avoided.
02316     ///
02317     /// \note the pointer to the sender object is not necessarily a poiner
02318     /// to an active object. In fact, typically QF::TICK() will be called from
02319     /// an interrupt, in which case you would create a unique object just to
02320     /// unambiguously identify the ISR as the sender of the time events.
02321     ///
02322     /// \sa QF::tick()
02323     #define TICK(sender_)                  tick(sender_)
02324 
02325     /// \brief Invoke the event publishing facility QF::publish(). This macro
02326     /// is the recommended way of publishing events, because it provides the
02327     /// vital information for software tracing and avoids any overhead when
02328     /// the tracing is disabled.
02329     ///
02330     ///
02331     /// This macro takes the last argument \a sender_, which is a pointer to
02332     /// the sender object. This argument is actually only used when QS
02333     /// tracing is enabled (macro #Q_SPY is defined). When QS software
02334     /// tracing is disabled, the macro calls QF::publish() without the
02335     /// \a sender_ argument, so the overhead of passing this extra argument
02336     /// is entirely avoided.
02337     ///
02338     /// \note the pointer to the sender object is not necessarily a poiner
02339     /// to an active object. In fact, if QF::PUBLISH() is called from an
02340     /// interrupt or other context, you can create a unique object just to
02341     /// unambiguously identify the publisher of the event.
02342     ///
02343     /// \sa QF::publish()
02344     #define PUBLISH(e_, sender_)           publish((e_), (sender_))
02345 
02346     /// \brief Invoke the direct event posting facility QActive::postFIFO().
02347     /// This macro is the recommended way of posting events, because it
02348     /// provides the vital information for software tracing and avoids any
02349     /// overhead when the tracing is disabled.
02350     ///
02351     ///
02352     /// This macro takes the last argument \a sender_, which is a pointer to
02353     /// the sender object. This argument is actually only used when QS
02354     /// tracing is disabled (macro #Q_SPY is defined). When QS software
02355     /// tracing is not enabled, the macro calls QF_publish() without the
02356     /// \a sender_ argument, so the overhead of passing this extra argument
02357     /// is entirely avoided.
02358     ///
02359     /// \note the pointer to the sender object is not necessarily a poiner
02360     /// to an active object. In fact, if ao->POST() is called from an
02361     /// interrupt or other context, you can create a unique object just to
02362     /// unambiguously identify the publisher of the event.
02363     ///
02364     /// \sa QActive::postFIFO()
02365     #define POST(e_, sender_)              postFIFO((e_), (sender_))
02366 
02367 #else
02368 
02369     #define TICK(dummy_)                   tick()
02370     #define PUBLISH(e_, dummy_)            publish(e_)
02371     #define POST(e_, dummy_)               postFIFO(e_)
02372 
02373 #endif                                                                // Q_SPY
02374 
02375 //////////////////////////////////////////////////////////////////////////////
02376 // QS software tracing
02377 #ifdef Q_SPY
02378 
02379 // qs.h ======================================================================
02380 /// \brief QS/C++ platform-independent public interface.
02381 /// This header file must be included directly or indirectly
02382 /// in all modules (*.cpp files) that use QS/C++.
02383 
02384 #ifndef Q_SPY
02385     #error "Q_SPY must be defined to include qs.h"
02386 #endif
02387 
02388 #ifndef Q_ROM                      // provide the default if Q_ROM NOT defined
02389     #define Q_ROM
02390 #endif
02391 #ifndef Q_ROM_VAR              // provide the default if Q_ROM_VAR NOT defined
02392     #define Q_ROM_VAR
02393 #endif
02394 #ifndef Q_ROM_BYTE            // provide the default if Q_ROM_BYTE NOT defined
02395     #define Q_ROM_BYTE(rom_var_)   (rom_var_)
02396 #endif
02397 
02398 #ifndef QS_TIME_SIZE
02399 
02400     /// \brief The size (in bytes) of the QS time stamp. Valid values: 1, 2,
02401     /// or 4; default 4.
02402     ///
02403     /// This macro can be defined in the QS port file (qs_port.h) to
02404     /// configure the ::QSTimeCtr type. Here the macro is not defined so the
02405     /// default of 4 byte is chosen.
02406     #define QS_TIME_SIZE 4
02407 #endif
02408 
02409 //////////////////////////////////////////////////////////////////////////////
02410 QP_BEGIN_
02411 
02412 /// \brief Quantum Spy record types.
02413 ///
02414 /// The following constants specify the QS record types used in QP components.
02415 /// You can specify your own record types starting from the ::QS_USER offset.
02416 /// Currently, the maximum of all records cannot exceed 256.
02417 /// \sa QS::filterOn()/#QS_FILTER_ON and QS::filterOff()/#QS_FILTER_OFF
02418 
02419 enum QSpyRecords {
02420     QS_QP_RESET,                 ///< reset the QP (start of a new QS session)
02421 
02422     // QEP records
02423     QS_QEP_STATE_ENTRY,                               ///< a state was entered
02424     QS_QEP_STATE_EXIT,                                 ///< a state was exited
02425     QS_QEP_STATE_INIT,          ///< an intial transition was taken in a state
02426     QS_QEP_INIT_TRAN,           ///< the top-most initial transition was taken
02427     QS_QEP_INTERN_TRAN,                  ///< an internal transition was taken
02428     QS_QEP_TRAN,                           ///< a regular transition was taken
02429     QS_QEP_IGNORED,             ///< an event was ignored (silently discarded)
02430     QS_QEP_DISPATCH,          ///< an event was dispatched (begin of RTC step)
02431     QS_QEP_UNHANDLED,               ///< an event was unhandled due to a guard
02432 
02433     // QF records
02434     QS_QF_ACTIVE_ADD,                ///< an AO has been added to QF (started)
02435     QS_QF_ACTIVE_REMOVE,         ///< an AO has been removed from QF (stopped)
02436     QS_QF_ACTIVE_SUBSCRIBE,                  ///< an AO subscribed to an event
02437     QS_QF_ACTIVE_UNSUBSCRIBE,              ///< an AO unsubscribed to an event
02438     QS_QF_ACTIVE_POST_FIFO,  ///< an event was posted (FIFO) directly to an AO
02439     QS_QF_ACTIVE_POST_LIFO,  ///< an event was posted (LIFO) directly to an AO
02440     QS_QF_ACTIVE_GET, ///< an AO got an event and its queue is still not empty
02441     QS_QF_ACTIVE_GET_LAST,      ///< an AO got an event and its queue is empty
02442     QS_QF_EQUEUE_INIT,                     ///< an event queue was initialized
02443     QS_QF_EQUEUE_POST_FIFO,     ///< an event was posted (FIFO) to a raw queue
02444     QS_QF_EQUEUE_POST_LIFO,     ///< an event was posted (LIFO) to a raw queue
02445     QS_QF_EQUEUE_GET,              ///< get an event and queue still not empty
02446     QS_QF_EQUEUE_GET_LAST,              ///< get the last event from the queue
02447     QS_QF_MPOOL_INIT,                       ///< a memory pool was initialized
02448     QS_QF_MPOOL_GET,        ///< a memory block was removed from a memory pool
02449     QS_QF_MPOOL_PUT,         ///< a memory block was returned to a memory pool
02450     QS_QF_PUBLISH,       ///< an event was truly published to some subscribers
02451     QS_QF_RESERVED8,
02452     QS_QF_NEW,                                         ///< new event creation
02453     QS_QF_GC_ATTEMPT,                          ///< garbage collection attempt
02454     QS_QF_GC,                                          ///< garbage collection
02455     QS_QF_TICK,                                     ///< QF::tick() was called
02456     QS_QF_TIMEEVT_ARM,                             ///< a time event was armed
02457     QS_QF_TIMEEVT_AUTO_DISARM,      ///< a time event expired and was disarmed
02458     QS_QF_TIMEEVT_DISARM_ATTEMPT,///< an attempt to disarmed a disarmed tevent
02459     QS_QF_TIMEEVT_DISARM,           ///< true disarming of an armed time event
02460     QS_QF_TIMEEVT_REARM,                         ///< rearming of a time event
02461     QS_QF_TIMEEVT_POST,      ///< a time event posted itself directly to an AO
02462     QS_QF_TIMEEVT_CTR,                 ///< a time event counter was requested
02463     QS_QF_CRIT_ENTRY,                        ///< critical section was entered
02464     QS_QF_CRIT_EXIT,                          ///< critical section was exited
02465     QS_QF_ISR_ENTRY,                                   ///< an ISR was entered
02466     QS_QF_ISR_EXIT,                                     ///< an ISR was exited
02467     QS_QF_INT_DISABLE,                           ///< interrupts were disabled
02468     QS_QF_INT_ENABLE,                             ///< interrupts were enabled
02469     QS_QF_RESERVED4,
02470     QS_QF_RESERVED3,
02471     QS_QF_RESERVED2,
02472     QS_QF_RESERVED1,
02473     QS_QF_RESERVED0,
02474 
02475     // QK records
02476     QS_QK_MUTEX_LOCK,                             ///< the QK mutex was locked
02477     QS_QK_MUTEX_UNLOCK,                         ///< the QK mutex was unlocked
02478     QS_QK_SCHEDULE,      ///< the QK scheduler scheduled a new task to execute
02479     QS_QK_RESERVED6,
02480     QS_QK_RESERVED5,
02481     QS_QK_RESERVED4,
02482     QS_QK_RESERVED3,
02483     QS_QK_RESERVED2,
02484     QS_QK_RESERVED1,
02485     QS_QK_RESERVED0,
02486 
02487     // Miscellaneous QS records
02488     QS_SIG_DIC,                                   ///< signal dictionary entry
02489     QS_OBJ_DIC,                                   ///< object dictionary entry
02490     QS_FUN_DIC,                                 ///< function dictionary entry
02491     QS_USR_DIC,                           ///< user QS record dictionary entry
02492     QS_RESERVED4,
02493     QS_RESERVED3,
02494     QS_RESERVED2,
02495     QS_RESERVED1,
02496     QS_RESERVED0,
02497     QS_ASSERT,                                ///< assertion fired in the code
02498 
02499     // User records
02500     QS_USER                ///< the first record available for user QS records
02501 };
02502 
02503 /// \brief Specification of all QS records for the QS::filterOn() and
02504 /// QS::filterOff()
02505 uint8_t const QS_ALL_RECORDS = static_cast<uint8_t>(0xFF);
02506 
02507 /// \brief Constant representing End-Of-Data condition returned from the
02508 /// QS::getByte() function.
02509 uint16_t const QS_EOD  = static_cast<uint16_t>(0xFFFF);
02510 
02511 
02512 #if (QS_TIME_SIZE == 1)
02513     typedef uint8_t QSTimeCtr;
02514     #define QS_TIME_()   (QP_ QS::u8_(QP_ QS::onGetTime()))
02515 #elif (QS_TIME_SIZE == 2)
02516     typedef uint16_t QSTimeCtr;
02517     #define QS_TIME_()   (QP_ QS::u16_(QP_ QS::onGetTime()))
02518 #elif (QS_TIME_SIZE == 4)
02519 
02520     /// \brief The type of the QS time stamp
02521     ///
02522     /// This type determines the dynamic range of QS time stamps
02523     typedef uint32_t QSTimeCtr;
02524 
02525     /// \brief Internal macro to output time stamp to the QS record
02526     #define QS_TIME_()   (QP_ QS::u32_(QP_ QS::onGetTime()))
02527 #else
02528     #error "QS_TIME_SIZE defined incorrectly, expected 1, 2, or 4"
02529 #endif
02530 
02531 /// \brief Quantum Spy logging facilities
02532 ///
02533 /// This class groups together QS services. It has only static members and
02534 /// should not be instantiated.
02535 class QS {
02536 public:
02537 
02538     /// \brief Get the current version of QS
02539     ///
02540     /// \return version of the QS as a constant 6-character string of the form
02541     /// x.y.zz, where x is a 1-digit major version number, y is a 1-digit
02542     /// minor version number, and zz is a 2-digit release number.
02543     static char_t const Q_ROM * Q_ROM_VAR getVersion(void);
02544 
02545     /// \brief Initialize the QS data buffer.
02546     ///
02547     /// This function should be called from QS_init() to provide QS with the
02548     /// data buffer. The first argument \a sto[] is the address of the memory
02549     /// block, and the second argument \a stoSize is the size of this block
02550     /// in bytes. Currently the size of the QS buffer cannot exceed 64KB.
02551     ///
02552     /// QS can work with quite small data buffers, but you will start losing
02553     /// data if the buffer is too small for the bursts of logging activity.
02554     /// The right size of the buffer depends on the data production rate and
02555     /// the data output rate. QS offers flexible filtering to reduce the data
02556     /// production rate.
02557     ///
02558     /// \note If the data output rate cannot keep up with the production rate,
02559     /// QS will start overwriting the older data with newer data. This is
02560     /// consistent with the "last-is-best" QS policy. The record sequence
02561     ///  counters and checksums on each record allow to easily detect data
02562     /// loss.
02563     static void initBuf(uint8_t sto[], uint32_t const stoSize);
02564 
02565     /// \brief Turn the global Filter on for a given record type \a rec.
02566     ///
02567     /// This function sets up the QS filter to enable the record type \a rec.
02568     /// The argument #QS_ALL_RECORDS specifies to filter-on all records.
02569     /// This function should be called indirectly through the macro
02570     /// #QS_FILTER_ON.
02571     ///
02572     /// \note Filtering based on the record-type is only the first layer of
02573     /// filtering. The second layer is based on the object-type. Both filter
02574     /// layers must be enabled for the QS record to be inserted into the QS
02575     /// buffer.
02576     /// \sa QS_filterOff(), #QS_FILTER_SM_OBJ, #QS_FILTER_AO_OBJ,
02577     /// #QS_FILTER_MP_OBJ, #QS_FILTER_EQ_OBJ, and #QS_FILTER_TE_OBJ.
02578     static void filterOn(uint8_t const rec);
02579 
02580     /// \brief Turn the global Filter off for a given record type \a rec.
02581     ///
02582     /// This function sets up the QS filter to disable the record type \a rec.
02583     /// The argument #QS_ALL_RECORDS specifies to suppress all records.
02584     /// This function should be called indirectly through the macro
02585     /// #QS_FILTER_OFF.
02586     ///
02587     /// \note Filtering records based on the record-type is only the first
02588     /// layer of filtering. The second layer is based on the object-type.
02589     /// Both filter layers must be enabled for the QS record to be inserted
02590     /// into the QS buffer.
02591     /// \sa
02592     static void filterOff(uint8_t const rec);
02593 
02594     /// \brief Mark the begin of a QS record \a rec
02595     ///
02596     /// This function must be called at the beginning of each QS record.
02597     /// This function should be called indirectly through the macro #QS_BEGIN,
02598     /// or #QS_BEGIN_NOCRIT, depending if it's called in a normal code or from
02599     /// a critical section.
02600     static void begin(uint8_t const rec);
02601 
02602     /// \brief Mark the end of a QS record \a rec
02603     ///
02604     /// This function must be called at the end of each QS record.
02605     /// This function should be called indirectly through the macro #QS_END,
02606     /// or #QS_END_NOCRIT, depending if it's called in a normal code or from
02607     /// a critical section.
02608     static void end(void);
02609 
02610     // unformatted data elements output ......................................
02611 
02612     /// \brief output uint8_t data element without format information
02613     /// \note This function is only to be used through macros, never in the
02614     /// client code directly.
02615     static void u8_(uint8_t const d);
02616 
02617     /// \brief Output uint16_t data element without format information
02618     /// \note This function is only to be used through macros, never in the
02619     /// client code directly.
02620     static void u16_(uint16_t d);
02621 
02622     /// \brief Output uint32_t data element without format information
02623     /// \note This function is only to be used through macros, never in the
02624     /// client code directly.
02625     static void u32_(uint32_t d);
02626 
02627     /// \brief Output zero-terminated ASCII string element without format
02628     /// information
02629     /// \note This function is only to be used through macros, never in the
02630     /// client code directly.
02631     static void str_(char_t const *s);
02632 
02633     /// \brief Output zero-terminated ASCII string element  allocated in ROM
02634     /// without format information
02635     /// \note This function is only to be used through macros, never in the
02636     /// client code directly.
02637     static void str_ROM_(char_t const Q_ROM * Q_ROM_VAR s);
02638 
02639     // formatted data elements output ........................................
02640 
02641     /// \brief Output uint8_t data element with format information
02642     /// \note This function is only to be used through macros, never in the
02643     /// client code directly.
02644     static void u8(uint8_t const format, uint8_t const d);
02645 
02646     /// \brief output uint16_t data element with format information
02647     /// \note This function is only to be used through macros, never in the
02648     /// client code directly.
02649     static void u16(uint8_t const format, uint16_t d);
02650 
02651     /// \brief Output uint32_t data element with format information
02652     /// \note This function is only to be used through macros, never in the
02653     /// client code directly.
02654     static void u32(uint8_t const format, uint32_t d);
02655 
02656     /// \brief Output 32-bit floating point data element with format
02657     /// information
02658     /// \note This function is only to be used through macros, never in the
02659     /// client code directly.
02660     static void f32(uint8_t const format, float32_t const d);
02661 
02662     /// \brief Output 64-bit floating point data element with format
02663     /// information
02664     /// \note This function is only to be used through macros, never in the
02665     /// client code directly.
02666     static void f64(uint8_t const format, float64_t const d);
02667 
02668     /// \brief Output zero-terminated ASCII string element with format
02669     /// information
02670     /// \note This function is only to be used through macros, never in the
02671     /// client code directly.
02672     static void str(char_t const *s);
02673 
02674     /// \brief Output zero-terminated ASCII string element allocated in ROM
02675     /// with format information
02676     /// \note This function is only to be used through macros, never in the
02677     /// client code directly.
02678     static void str_ROM(char_t const Q_ROM * Q_ROM_VAR s);
02679 
02680     /// \brief Output memory block of up to 255-bytes with format information
02681     /// \note This function is only to be used through macros, never in the
02682     /// client code directly.
02683     static void mem(uint8_t const *blk, uint8_t size);
02684 
02685 #if (QS_OBJ_PTR_SIZE == 8) || (QS_FUN_PTR_SIZE == 8)
02686     /// \brief Output uint64_t data element without format information
02687     /// \note This function is only to be used through macros, never in the
02688     /// client code directly.
02689     static void u64_(uint64_t d);
02690 
02691     /// \brief Output uint64_t data element with format information
02692     /// \note This function is only to be used through macros, never in the
02693     /// client code directly.
02694     static void u64(uint8_t format, uint64_t d);
02695 #endif
02696 
02697     // QS buffer access ......................................................
02698 
02699     /// \brief Byte-oriented interface to the QS data buffer.
02700     ///
02701     /// This function delivers one byte at a time from the QS data buffer.
02702     /// The function returns the byte in the least-significant 8-bits of the
02703     /// 16-bit return value if the byte is available. If no more data is
02704     /// available at the time, the function returns QS_EOD (End-Of-Data).
02705     ///
02706     /// \note QS::getByte() is NOT protected with a critical section.
02707     static uint16_t getByte(void);
02708 
02709     /// \brief Block-oriented interface to the QS data buffer.
02710     ///
02711     /// This function delivers a contiguous block of data from the QS data
02712     /// buffer. The function returns the pointer to the beginning of the
02713     /// block, and writes the number of bytes in the block to the location
02714     /// pointed to by \a pNbytes. The argument \a pNbytes is also used as
02715     /// input to provide the maximum size of the data block that the caller
02716     /// can accept.
02717     ///
02718     /// If no bytes are available in the QS buffer when the function is
02719     /// called, the function returns a NULL pointer and sets the value
02720     /// pointed to by \a pNbytes to zero.
02721     ///
02722     /// \note Only the NULL return from QS::getBlock() indicates that the QS
02723     /// buffer is empty at the time of the call. The non-NULL return often
02724     /// means that the block is at the end of the buffer and you need to call
02725     /// QS::getBlock() again to obtain the rest of the data that "wrapped
02726     /// around" to the beginning of the QS data buffer.
02727     ///
02728     /// \note QS::getBlock() is NOT protected with a critical section.
02729     static uint8_t const *getBlock(uint16_t * const pNbytes);
02730 
02731     //////////////////////////////////////////////////////////////////////////
02732     // platform-dependent callback functions to be implemented by clients
02733 
02734     // platform-specific callback functions, need to be implemented by clients
02735     /// \brief Callback to startup the QS facility
02736     ///
02737     /// This is a platform-dependent "callback" function invoked through the
02738     /// macro #QS_INIT. You need to implement this function in your
02739     /// application. At a minimum, the function must configure the QS buffer
02740     /// by calling QS::initBuf(). Typically, you will also want to open/
02741     /// configure the QS output channel, such as a serial port, or a file.
02742     /// The void* argument \a arg can be used to pass parameter(s) needed to
02743     /// configure the output channel.
02744     ///
02745     /// The function returns true if the QS initialization was successful,
02746     /// or false if it failed.
02747     ///
02748     /// The following example illustrates an implementation of QS_onStartup():
02749     /// \include qs_startup.cpp
02750     static bool onStartup(void const *arg);
02751 
02752     /// \brief Callback to cleanup the QS facility
02753     ///
02754     /// This is a platform-dependent "callback" function invoked through the
02755     /// macro #QS_EXIT. You need to implement this function in your
02756     /// application. The main purpose of this function is to close the QS
02757     /// output channel, if necessary.
02758     static void onCleanup(void);
02759 
02760     /// \brief Callback to flush the QS trace data to the host
02761     ///
02762     /// This is a platform-dependent "callback" function to flush the QS
02763     /// trace buffer to the host. The function typically busy-waits until all
02764     /// the data in the buffer is sent to the host. This is acceptable only
02765     /// in the initial transient.
02766     static void onFlush(void);
02767 
02768     /// \brief Callback to obtain a timestamp for a QS record.
02769     ///
02770     /// This is a platform-dependent "callback" function invoked from the
02771     /// macro #QS_TIME_ to add the time stamp to the QS record.
02772     ///
02773     /// \note Some of the pre-defined QS records from QP do not output the
02774     /// time stamp. However, ALL user records do output the time stamp.
02775     /// \note QS::onGetTime() is called in a critical section and should not
02776     /// exit critical section.
02777     ///
02778     /// The following example shows using a system call to implement QS
02779     /// time stamping:
02780     /// \include qs_onGetTime.cpp
02781     static QSTimeCtr onGetTime(void);
02782 
02783     //////////////////////////////////////////////////////////////////////////
02784     // Global and Local QS filters
02785     static uint8_t glbFilter_[32];                ///< global on/off QS filter
02786     static void const *smObj_;         ///< state machine for QEP local filter
02787     static void const *aoObj_;       ///< active object for QF/QK local filter
02788     static void const *mpObj_;            ///<  event pool for QF local filter
02789     static void const *eqObj_;             ///<  raw queue for QF local filter
02790     static void const *teObj_;            ///<  time event for QF local filter
02791     static void const *apObj_;///<  generic object Application QF local filter
02792 
02793     //////////////////////////////////////////////////////////////////////////
02794     // Miscallaneous
02795                                     /// tick counter for the QS_QF_TICK record
02796     static QSTimeCtr tickCtr_;
02797 };
02798 
02799 /// \brief Enumerates data formats recognized by QS
02800 ///
02801 /// QS uses this enumeration is used only internally for the formatted user
02802 /// data elements.
02803 enum QSType {
02804     QS_I8_T,                                  ///< signed 8-bit integer format
02805     QS_U8_T,                                ///< unsigned 8-bit integer format
02806     QS_I16_T,                                ///< signed 16-bit integer format
02807     QS_U16_T,                              ///< unsigned 16-bit integer format
02808     QS_I32_T,                                ///< signed 32-bit integer format
02809     QS_U32_T,                              ///< unsigned 32-bit integer format
02810     QS_F32_T,                                ///< 32-bit floating point format
02811     QS_F64_T,                                ///< 64-bit floating point format
02812     QS_STR_T,                         ///< zero-terminated ASCII string format
02813     QS_MEM_T,                         ///< up to 255-bytes memory block format
02814     QS_SIG_T,                                         ///< event signal format
02815     QS_OBJ_T,                                       ///< object pointer format
02816     QS_FUN_T,                                     ///< function pointer format
02817     QS_I64_T,                                ///< signed 64-bit integer format
02818     QS_U64_T,                              ///< unsigned 64-bit integer format
02819     QS_U32_HEX_T                    ///< unsigned 32-bit integer in hex format
02820 };
02821 
02822 /// \brief critical section nesting level
02823 ///
02824 /// \note Not to be used by Clients directly, only in ports of QF
02825 extern uint8_t QF_critNest_;
02826 
02827 QP_END_
02828 
02829 
02830 //////////////////////////////////////////////////////////////////////////////
02831 // Macros for adding QS instrumentation to the client code
02832 
02833 /// \brief Initialize the QS facility.
02834 ///
02835 /// This macro provides an indirection layer to invoke the QS initialization
02836 /// routine if #Q_SPY is defined, or do nothing if #Q_SPY is not defined.
02837 /// \sa QS::onStartup(), example of setting up a QS filter in #QS_FILTER_IN
02838 #define QS_INIT(arg_)           (QP_ QS::onStartup(arg_))
02839 
02840 /// \brief Cleanup the QS facility.
02841 ///
02842 /// This macro provides an indirection layer to invoke the QS cleanup
02843 /// routine if #Q_SPY is defined, or do nothing if #Q_SPY is not defined.
02844 /// \sa QS::onCleanup()
02845 #define QS_EXIT()               (QP_ QS::onCleanup())
02846 
02847 /// \brief Global Filter ON for a given record type \a rec.
02848 ///
02849 /// This macro provides an indirection layer to call QS::filterOn() if #Q_SPY
02850 /// is defined, or do nothing if #Q_SPY is not defined.
02851 ///
02852 /// The following example shows how to use QS filters:
02853 /// \include qs_filter.cpp
02854 #define QS_FILTER_ON(rec_)      (QP_ QS::filterOn(static_cast<uint8_t>(rec_)))
02855 
02856 /// \brief Global filter OFF for a given record type \a rec.
02857 ///
02858 /// This macro provides an indirection layer to call QS::filterOff() if #Q_SPY
02859 /// is defined, or do nothing if #Q_SPY is not defined.
02860 ///
02861 /// \sa Example of using QS filters in #QS_FILTER_ON documentation
02862 #define QS_FILTER_OFF(rec_)    (QP_ QS::filterOff(static_cast<uint8_t>(rec_)))
02863 
02864 /// \brief Local Filter for a given state machine object \a obj_.
02865 ///
02866 /// This macro sets up the state machine object local filter if #Q_SPY is
02867 /// defined, or does nothing if #Q_SPY is not defined. The argument \a obj_
02868 /// is the pointer to the state machine object that you want to monitor.
02869 ///
02870 /// The state machine object filter allows you to filter QS records pertaining
02871 /// only to a given state machine object. With this filter disabled, QS will
02872 /// output records from all state machines in your application. The object
02873 /// filter is disabled by setting the state machine pointer to NULL.
02874 ///
02875 /// The state machine filter affects the following QS records:
02876 /// ::QS_QEP_STATE_ENTRY, ::QS_QEP_STATE_EXIT, ::QS_QEP_STATE_INIT,
02877 /// ::QS_QEP_INIT_TRAN, ::QS_QEP_INTERN_TRAN, ::QS_QEP_TRAN,
02878 /// and ::QS_QEP_IGNORED.
02879 ///
02880 /// \note Because active objects are state machines at the same time,
02881 /// the state machine filter (#QS_FILTER_SM_OBJ) pertains to active
02882 /// objects as well. However, the state machine filter is more general,
02883 /// because it can be used only for state machines that are not active
02884 /// objects, such as "Orthogonal Components".
02885 ///
02886 /// \sa Example of using QS filters in #QS_FILTER_ON documentation
02887 #define QS_FILTER_SM_OBJ(obj_)  (QP_ QS::smObj_ = (obj_))
02888 
02889 /// \brief Local Filter for a given active object \a obj_.
02890 ///
02891 /// This macro sets up the active object local filter if #Q_SPY is defined,
02892 /// or does nothing if #Q_SPY is not defined. The argument \a obj_ is the
02893 /// pointer to the active object that you want to monitor.
02894 ///
02895 /// The active object filter allows you to filter QS records pertaining
02896 /// only to a given active object. With this filter disabled, QS will
02897 /// output records from all active objects in your application. The object
02898 /// filter is disabled by setting the active object pointer \a obj_ to NULL.
02899 ///
02900 /// The active object filter affects the following QS records:
02901 /// ::QS_QF_ACTIVE_ADD, ::QS_QF_ACTIVE_REMOVE, ::QS_QF_ACTIVE_SUBSCRIBE,
02902 /// ::QS_QF_ACTIVE_UNSUBSCRIBE, ::QS_QF_ACTIVE_POST_FIFO,
02903 /// ::QS_QF_ACTIVE_POST_LIFO, ::QS_QF_ACTIVE_GET, and ::QS_QF_ACTIVE_GET_LAST.
02904 ///
02905 /// \sa Example of using QS filters in #QS_FILTER_ON documentation
02906 #define QS_FILTER_AO_OBJ(obj_)  (QP_ QS::aoObj_ = (obj_))
02907 
02908 /// \brief Local Filter for a given memory pool object \a obj_.
02909 ///
02910 /// This macro sets up the memory pool object local filter if #Q_SPY is
02911 /// defined, or does nothing if #Q_SPY is not defined. The argument \a obj_
02912 /// is the pointer to the memory buffer used during the initialization of the
02913 /// event pool with QF::poolInit().
02914 ///
02915 /// The memory pool filter allows you to filter QS records pertaining
02916 /// only to a given memory pool. With this filter disabled, QS will
02917 /// output records from all memory pools in your application. The object
02918 /// filter is disabled by setting the memory pool pointer \a obj_ to NULL.
02919 ///
02920 /// The memory pool filter affects the following QS records:
02921 /// ::QS_QF_MPOOL_INIT, ::QS_QF_MPOOL_GET, and ::QS_QF_MPOOL_PUT.
02922 ///
02923 /// \sa Example of using QS filters in #QS_FILTER_ON documentation
02924 #define QS_FILTER_MP_OBJ(obj_)  (QP_ QS::mpObj_ = (obj_))
02925 
02926 /// \brief Filter for a given event queue object \a obj_.
02927 ///
02928 /// This macro sets up the event queue object filter if #Q_SPY is defined,
02929 /// or does nothing if #Q_SPY is not defined. The argument \a obj_ is the
02930 /// pointer to the "raw" thread-safe queue object you want to monitor.
02931 ///
02932 /// The event queue filter allows you to filter QS records pertaining
02933 /// only to a given event queue. With this filter disabled, QS will
02934 /// output records from all event queues in your application. The object
02935 /// filter is disabled by setting the event queue pointer \a obj_ to NULL.
02936 ///
02937 /// The event queue filter affects the following QS records:
02938 /// ::QS_QF_EQUEUE_INIT, ::QS_QF_EQUEUE_POST_FIFO, ::QS_QF_EQUEUE_POST_LIFO,
02939 /// ::QS_QF_EQUEUE_GET, and ::QS_QF_EQUEUE_GET_LAST.
02940 ///
02941 /// \sa Example of using QS filters in #QS_FILTER_IN documentation
02942 #define QS_FILTER_EQ_OBJ(obj_)  (QP_ QS::eqObj_ = (obj_))
02943 
02944 /// \brief Local Filter for a given time event object \a obj_.
02945 ///
02946 /// This macro sets up the time event object local filter if #Q_SPY is
02947 /// defined, or does nothing if #Q_SPY is not defined. The argument \a obj_
02948 /// is the pointer to the time event object you want to monitor.
02949 ///
02950 /// The time event filter allows you to filter QS records pertaining
02951 /// only to a given time event. With this filter disabled, QS will
02952 /// output records from all time events in your application. The object
02953 /// filter is disabled by setting the time event pointer \a obj_ to NULL.
02954 ///
02955 /// The time event filter affects the following QS records:
02956 /// ::QS_QF_TIMEEVT_ARM, ::QS_QF_TIMEEVT_AUTO_DISARM,
02957 /// ::QS_QF_TIMEEVT_DISARM_ATTEMPT, ::QS_QF_TIMEEVT_DISARM,
02958 /// ::QS_QF_TIMEEVT_REARM, ::QS_QF_TIMEEVT_POST, and ::QS_QF_TIMEEVT_PUBLISH.
02959 ///
02960 /// \sa Example of using QS filters in #QS_FILTER_ON documentation
02961 #define QS_FILTER_TE_OBJ(obj_)  (QP_ QS::teObj_ = (obj_))
02962 
02963 /// \brief Local Filter for a generic application object \a obj_.
02964 ///
02965 /// This macro sets up the local application object filter if #Q_SPY is
02966 /// defined, or does nothing if #Q_SPY is not defined. The argument \a obj_
02967 /// is the pointer to the application object you want to monitor.
02968 ///
02969 /// The application object filter allows you to filter QS records pertaining
02970 /// only to a given application object. With this filter disabled, QS will
02971 /// output records from all application-records enabled by the global filter.
02972 /// The local filter is disabled by setting the time event pointer \a obj_
02973 /// to NULL.
02974 ///
02975 /// \sa Example of using QS filters in #QS_FILTER_ON documentation
02976 #define QS_FILTER_AP_OBJ(obj_)  (QP_ QS::apObj_ = (obj_))
02977 
02978 
02979 //////////////////////////////////////////////////////////////////////////////
02980 // Macros to generate user QS records
02981 
02982 #define QS_GLB_FILTER_(rec_) \
02983     ((QP_ QS::glbFilter_[static_cast<uint8_t>(rec_) >> 3] \
02984       & (static_cast<uint8_t>(1U << (static_cast<uint8_t>(rec_) \
02985                                      & static_cast<uint8_t>(7))))) \
02986              != static_cast<uint8_t>(0))
02987 
02988 /// \brief Begin a QS user record without entering critical section.
02989 #define QS_BEGIN_NOCRIT(rec_, obj_) \
02990     if (QS_GLB_FILTER_(rec_) \
02991         && ((QP_ QS::apObj_ == static_cast<void *>(0)) \
02992             || (QP_ QS::apObj_ == (obj_)))) \
02993     { \
02994         QP_ QS::begin(static_cast<uint8_t>(rec_)); \
02995         QS_TIME_();
02996 
02997 /// \brief End a QS user record without exiting critical section.
02998 #define QS_END_NOCRIT() \
02999     QS_END_NOCRIT_()
03000 
03001                                                // QS-specific critical section
03002 #ifndef QF_CRIT_STAT_TYPE
03003     /// \brief This is an internal macro for defining the critical section
03004     /// status type.
03005     ///
03006     /// The purpose of this macro is to enable writing the same code for the
03007     /// case when critical sectgion status type is defined and when it is not.
03008     /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
03009     /// provides the definition of the critical section status variable.
03010     /// Otherwise this macro is empty.
03011     /// \sa #QF_CRIT_STAT_TYPE
03012     ///
03013     #define QS_CRIT_STAT_
03014 
03015     /// \brief This is an internal macro for entering a critical section.
03016     ///
03017     /// The purpose of this macro is to enable writing the same code for the
03018     /// case when critical sectgion status type is defined and when it is not.
03019     /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
03020     /// invokes #QF_CRIT_ENTRY passing the key variable as the parameter.
03021     /// Otherwise #QF_CRIT_ENTRY is invoked with a dummy parameter.
03022     /// \sa #QF_CRIT_ENTRY
03023     ///
03024     #define QS_CRIT_ENTRY_()    QF_CRIT_ENTRY(dummy)
03025 
03026     /// \brief This is an internal macro for exiting a cricial section.
03027     ///
03028     /// The purpose of this macro is to enable writing the same code for the
03029     /// case when critical sectgion status type is defined and when it is not.
03030     /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
03031     /// invokes #QF_CRIT_EXIT passing the key variable as the parameter.
03032     /// Otherwise #QF_CRIT_EXIT is invoked with a dummy parameter.
03033     /// \sa #QF_CRIT_EXIT
03034     ///
03035     #define QS_CRIT_EXIT_()     QF_CRIT_EXIT(dummy)
03036 
03037 #else
03038     #define QS_CRIT_STAT_       QF_CRIT_STAT_TYPE critStat_;
03039     #define QS_CRIT_ENTRY_()    QF_CRIT_ENTRY(critStat_)
03040     #define QS_CRIT_EXIT_()     QF_CRIT_EXIT(critStat_)
03041 #endif
03042 
03043 /// \brief Begin a user QS record with entering critical section.
03044 ///
03045 /// The following example shows how to build a user QS record using the
03046 /// macros #QS_BEGIN, #QS_END, and the formatted output macros: #QS_U8 and
03047 /// #QS_STR.
03048 /// \include qs_user.cpp
03049 /// \note Must always be used in pair with #QS_END
03050 #define QS_BEGIN(rec_, obj_) \
03051     if (QS_GLB_FILTER_(rec_) \
03052         && ((QP_ QS::apObj_ == static_cast<void *>(0)) \
03053             || (QP_ QS::apObj_ == (obj_)))) \
03054     { \
03055         QS_CRIT_STAT_ \
03056         QS_CRIT_ENTRY_(); \
03057         QP_ QS::begin(static_cast<uint8_t>(rec_)); \
03058         QS_TIME_();
03059 
03060 /// \brief End a QS record with exiting critical section.
03061 /// \sa example for #QS_BEGIN
03062 /// \note Must always be used in pair with #QS_BEGIN
03063 #define QS_END() \
03064     QS_END_()
03065 
03066 
03067 //////////////////////////////////////////////////////////////////////////////
03068 // Macros for use inside other macros or internally in the QP code
03069 
03070 /// \brief Internal QS macro to begin a QS record with entering critical
03071 /// section.
03072 /// \note This macro is intended to use only inside QP components and NOT
03073 /// at the application level. \sa #QS_BEGIN
03074 #define QS_BEGIN_(rec_, objFilter_, obj_) \
03075     if (QS_GLB_FILTER_(rec_) \
03076         && (((objFilter_) == static_cast<void *>(0)) \
03077             || ((objFilter_) == (obj_)))) \
03078     { \
03079         QS_CRIT_ENTRY_(); \
03080         QP_ QS::begin(static_cast<uint8_t>(rec_));
03081 
03082 /// \brief  Internal QS macro to end a QS record with exiting critical
03083 /// section.
03084 /// \note This macro is intended to use only inside QP components and NOT
03085 /// at the application level. \sa #QS_END
03086 #define QS_END_() \
03087         QP_ QS::end(); \
03088         QS_CRIT_EXIT_(); \
03089     }
03090 
03091 /// \brief Internal QS macro to begin a QS record without entering critical
03092 /// section.
03093 /// \note This macro is intended to use only inside QP components and NOT
03094 /// at the application level. \sa #QS_BEGIN_NOCRIT
03095 #define QS_BEGIN_NOCRIT_(rec_, objFilter_, obj_) \
03096     if (QS_GLB_FILTER_(rec_) \
03097         && (((objFilter_) == static_cast<void *>(0)) \
03098             || ((objFilter_) == (obj_)))) \
03099     { \
03100         QP_ QS::begin(static_cast<uint8_t>(rec_));
03101 
03102 /// \brief Internal QS macro to end a QS record without exiting critical
03103 /// section.
03104 /// \note This macro is intended to use only inside QP components and NOT
03105 /// at the application level. \sa #QS_END_NOCRIT
03106 #define QS_END_NOCRIT_() \
03107         QP_ QS::end(); \
03108     }
03109 
03110 #if (Q_SIGNAL_SIZE == 1)
03111     /// \brief Internal QS macro to output an unformatted event signal
03112     /// data element
03113     /// \note the size of the pointer depends on the macro #Q_SIGNAL_SIZE.
03114     #define QS_SIG_(sig_)    (QP_ QS::u8_(static_cast<uint8_t>(sig_))))
03115 #elif (Q_SIGNAL_SIZE == 2)
03116     #define QS_SIG_(sig_)    (QP_ QS::u16_(static_cast<uint16_t>(sig_)))
03117 #elif (Q_SIGNAL_SIZE == 4)
03118     #define QS_SIG_(sig_)    (QP_ QS::u32_(static_cast<uint32_t>(sig_)))
03119 #endif
03120 
03121 /// \brief Internal QS macro to output an unformatted uint8_t data element
03122 #define QS_U8_(data_)        (QP_ QS::u8_(data_))
03123 
03124 /// \brief Internal QS macro to output an unformatted uint16_t data element
03125 #define QS_U16_(data_)       (QP_ QS::u16_(data_))
03126 
03127 /// \brief Internal QS macro to output an unformatted uint32_t data element
03128 #define QS_U32_(data_)       (QP_ QS::u32_(data_))
03129 
03130 
03131 #if (QS_OBJ_PTR_SIZE == 1)
03132     #define QS_OBJ_(obj_)    (QP_ QS::u8_(reinterpret_cast<uint8_t>(obj_)))
03133 #elif (QS_OBJ_PTR_SIZE == 2)
03134     #define QS_OBJ_(obj_)    (QP_ QS::u16_(reinterpret_cast<uint16_t>(obj_)))
03135 #elif (QS_OBJ_PTR_SIZE == 4)
03136     #define QS_OBJ_(obj_)    (QP_ QS::u32_(reinterpret_cast<uint32_t>(obj_)))
03137 #elif (QS_OBJ_PTR_SIZE == 8)
03138     #define QS_OBJ_(obj_)    (QP_ QS::u64_(reinterpret_cast<uint64_t>(obj_)))
03139 #else
03140 
03141     /// \brief Internal QS macro to output an unformatted object pointer
03142     /// data element
03143     /// \note the size of the pointer depends on the macro #QS_OBJ_PTR_SIZE.
03144     /// If the size is not defined the size of pointer is assumed 4-bytes.
03145     #define QS_OBJ_(obj_)    (QP_ QS::u32_(reinterpret_cast<uint32_t>(obj_)))
03146 #endif
03147 
03148 
03149 #if (QS_FUN_PTR_SIZE == 1)
03150     #define QS_FUN_(fun_)    (QP_ QS::u8_(reinterpret_cast<uint8_t>(fun_)))
03151 #elif (QS_FUN_PTR_SIZE == 2)
03152     #define QS_FUN_(fun_)    (QP_ QS::u16_(reinterpret_cast<uint16_t>(fun_)))
03153 #elif (QS_FUN_PTR_SIZE == 4)
03154     #define QS_FUN_(fun_)    (QP_ QS::u32_(reinterpret_cast<uint32_t>(fun_)))
03155 #elif (QS_FUN_PTR_SIZE == 8)
03156     #define QS_FUN_(fun_)    (QP_ QS::u64_(reinterpret_cast<uint64_t>(fun_)))
03157 #else
03158 
03159     /// \brief Internal QS macro to output an unformatted function pointer
03160     /// data element
03161     /// \note the size of the pointer depends on the macro #QS_FUN_PTR_SIZE.
03162     /// If the size is not defined the size of pointer is assumed 4-bytes.
03163     #define QS_FUN_(fun_)    (QP_ QS::u32_(reinterpret_cast<uint32_t>(fun_)))
03164 #endif
03165 
03166 /// \brief Internal QS macro to output a zero-terminated ASCII string
03167 /// data element
03168 #define QS_STR_(msg_)        (QP_ QS::str_(msg_))
03169 
03170 /// \brief Internal QS macro to output a zero-terminated ASCII string
03171 /// allocated in ROM data element
03172 #define QS_STR_ROM_(msg_)    (QP_ QS::str_ROM_(msg_))
03173 
03174 //////////////////////////////////////////////////////////////////////////////
03175 // Macros for use in the client code
03176 
03177 /// \brief Output formatted int8_t to the QS record
03178 #define QS_I8(width_, data_) \
03179     (QP_ QS::u8(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
03180         | static_cast<uint8_t>(QP_ QS_I8_T)), (data_)))
03181 
03182 /// \brief Output formatted uint8_t to the QS record
03183 #define QS_U8(width_, data_) \
03184     (QP_ QS::u8(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
03185         | static_cast<uint8_t>(QP_ QS_U8_T)), (data_)))
03186 
03187 /// \brief Output formatted int16_t to the QS record
03188 #define QS_I16(width_, data_) \
03189     (QP_ QS::u16(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
03190         | static_cast<uint8_t>(QP_ QS_I16_T)), (data_)))
03191 
03192 /// \brief Output formatted uint16_t to the QS record
03193 #define QS_U16(width_, data_) \
03194     (QP_ QS::u16(static_cast<uint8_t>((((width_) << 4)) \
03195         | static_cast<uint8_t>(QP_ QS_U16_T)), (data_)))
03196 
03197 /// \brief Output formatted int32_t to the QS record
03198 #define QS_I32(width_, data_) \
03199     (QP_ QS::u32(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
03200         | static_cast<uint8_t>(QP_ QS_I32_T)), (data_)))
03201 
03202 /// \brief Output formatted uint32_t to the QS record
03203 #define QS_U32(width_, data_) \
03204     (QP_ QS::u32(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
03205         | static_cast<uint8_t>(QP_ QS_U32_T)), (data_)))
03206 
03207 /// \brief Output formatted 32-bit floating point number to the QS record
03208 #define QS_F32(width_, data_) \
03209     QP_ QS::f32(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
03210         | static_cast<uint8_t>(QP_ QS_F32_T)), (data_)))
03211 
03212 /// \brief Output formatted 64-bit floating point number to the QS record
03213 #define QS_F64(width_, data_) \
03214     (QP_ QS::f64(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
03215         | static_cast<uint8_t>(QP_ QS_F64_T)), (data_)))
03216 
03217 /// \brief Output formatted int64_t to the QS record
03218 #define QS_I64(width_, data_) \
03219     (QP_ QS::u64(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
03220         | static_cast<uint8_t>(QP_ QS_I64_T)), (data_)))
03221 
03222 /// \brief Output formatted uint64_t to the QS record
03223 #define QS_U64(width_, data_) \
03224     (QP_ QS::u64(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
03225         | static_cast<uint8_t>(QP_ QS_U64_T)), (data_)))
03226 
03227 /// \brief Output formatted uint32_t to the QS record
03228 #define QS_U32_HEX(width_, data_) \
03229     (QP_ QS::u32(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
03230         | static_cast<uint8_t>(QP_ QS_U32_HEX_T)), (data_)))
03231 
03232 /// \brief Output formatted zero-terminated ASCII string to the QS record
03233 #define QS_STR(str_)            (QP_ QS::str(str_))
03234 
03235 /// \brief Output formatted zero-terminated ASCII string from ROM
03236 /// to the QS record
03237 #define QS_STR_ROM(str_)        (QP_ QS::str_ROM(str_))
03238 
03239 /// \brief Output formatted memory block of up to 255 bytes to the QS
03240 /// record
03241 #define QS_MEM(mem_, size_)     (QP_ QS::mem((mem_), (size_)))
03242 
03243 
03244 #if (QS_OBJ_PTR_SIZE == 1)
03245     #define QS_OBJ(obj_)        (QP_ QS::u8(QS_OBJ_T, (uint8_t)(obj_)))
03246 #elif (QS_OBJ_PTR_SIZE == 2)
03247     #define QS_OBJ(obj_)        (QP_ QS::u16(QS_OBJ_T, (uint16_t)(obj_)))
03248 #elif (QS_OBJ_PTR_SIZE == 4)
03249     #define QS_OBJ(obj_)        (QP_ QS::u32(QS_OBJ_T, (uint32_t)(obj_)))
03250 #elif (QS_OBJ_PTR_SIZE == 8)
03251     #define QS_OBJ(obj_)        (QP_ QS::u64(QS_OBJ_T, (uint64_t)(obj_)))
03252 #else
03253     /// \brief Output formatted object pointer to the QS record
03254     #define QS_OBJ(obj_)        (QP_ QS::u32(QS_OBJ_T, (uint32_t)(obj_)))
03255 #endif
03256 
03257 
03258 #if (QS_FUN_PTR_SIZE == 1)
03259     #define QS_FUN(fun_)        (QP_ QS::u8(QS_FUN_T, (uint8_t)(fun_)))
03260 #elif (QS_FUN_PTR_SIZE == 2)
03261     #define QS_FUN(fun_)        (QP_ QS::u16(QS_FUN_T, (uint16_t)(fun_)))
03262 #elif (QS_FUN_PTR_SIZE == 4)
03263     #define QS_FUN(fun_)        (QP_ QS::u32(QS_FUN_T, (uint32_t)(fun_)))
03264 #elif (QS_FUN_PTR_SIZE == 8)
03265     #define QS_FUN(fun_)        (QP_ QS::u64(QS_FUN_T, (uint64_t)(fun_)))
03266 #else
03267     /// \brief Output formatted function pointer to the QS record
03268     #define QS_FUN(fun_)        (QP_ QS::u32(QS_FUN_T, (uint32_t)(fun_)))
03269 #endif
03270 
03271 
03272 /// \brief Reset the QS session.
03273 ///
03274 /// This trace record should be generated at the beginning of the QS session.
03275 /// It informs the QSPY host application that the new session has been started.
03276 #define QS_RESET() do { \
03277     if (QS_GLB_FILTER_(QP_ QS_QP_RESET)) { \
03278         QS_CRIT_STAT_ \
03279         QS_CRIT_ENTRY_(); \
03280         QP_ QS::begin(static_cast<uint8_t>(QP_ QS_QP_RESET)); \
03281         QP_ QS::end(); \
03282         QS_CRIT_EXIT_(); \
03283         QP_ QS::onFlush(); \
03284     } \
03285 } while (false)
03286 
03287 /// \brief Output signal dictionary record
03288 ///
03289 /// A signal dictionary record associates the numerical value of the signal
03290 /// and the binary address of the state machine that consumes that signal
03291 /// with the human-readable name of the signal.
03292 ///
03293 /// Providing a signal dictionary QS record can vastly improve readability of
03294 /// the QS log, because instead of dealing with cryptic machine addresses the
03295 /// QSpy host utility can display human-readable names.
03296 ///
03297 /// A signal dictionary entry is associated with both the signal value \a sig_
03298 /// and the state machine \a obj_, because signals are required to be unique
03299 /// only within a given state machine and therefore the same numerical values
03300 /// can represent different signals in different state machines.
03301 ///
03302 /// For the "global" signals that have the same meaning in all state machines
03303 /// (such as globally published signals), you can specify a signal dictionary
03304 /// entry with the \a obj_ parameter set to NULL.
03305 ///
03306 /// The following example shows the definition of signal dictionary entries
03307 /// in the initial transition of the Table active object. Please note that
03308 /// signals HUNGRY_SIG and DONE_SIG are associated with the Table state
03309 /// machine only ("me" \a obj_ pointer). The EAT_SIG signal, on the other
03310 /// hand, is global (0 \a obj_ pointer):
03311 /// \include qs_sigDic.cpp
03312 ///
03313 /// \note The QSpy log utility must capture the signal dictionary record
03314 /// in order to use the human-readable information. You need to connect to
03315 /// the target before the dictionary entries have been transmitted.
03316 ///
03317 /// The following QSpy log example shows the signal dictionary records
03318 /// generated from the Table initial transition and subsequent records that
03319 /// show human-readable names of the signals:
03320 /// \include qs_sigLog.txt
03321 ///
03322 /// The following QSpy log example shows the same sequence of records, but
03323 /// with dictionary records removed. The human-readable signal names are not
03324 /// available.
03325 /// \include qs_sigLog0.txt
03326 #define QS_SIG_DICTIONARY(sig_, obj_) do { \
03327     if (QS_GLB_FILTER_(QP_ QS_SIG_DIC)) { \
03328         static char_t const Q_ROM Q_ROM_VAR sig_name_[] = #sig_; \
03329         QS_CRIT_STAT_ \
03330         QS_CRIT_ENTRY_(); \
03331         QP_ QS::begin(static_cast<uint8_t>(QP_ QS_SIG_DIC)); \
03332         QS_SIG_(sig_); \
03333         QS_OBJ_(obj_); \
03334         QS_STR_ROM_(&sig_name_[0]); \
03335         QP_ QS::end(); \
03336         QS_CRIT_EXIT_(); \
03337         QP_ QS::onFlush(); \
03338     } \
03339 } while (false)
03340 
03341 /// \brief Output object dictionary record
03342 ///
03343 /// An object dictionary record associates the binary address of an object
03344 /// in the target's memory with the human-readable name of the object.
03345 ///
03346 /// Providing an object dictionary QS record can vastly improve readability of
03347 /// the QS log, because instead of dealing with cryptic machine addresses the
03348 /// QSpy host utility can display human-readable object names.
03349 ///
03350 /// The following example shows the definition of object dictionary entry
03351 /// for the Table active object:
03352 /// \include qs_objDic.cpp
03353 #define QS_OBJ_DICTIONARY(obj_) do { \
03354     if (QS_GLB_FILTER_(QP_ QS_OBJ_DIC)) { \
03355         static char_t const Q_ROM Q_ROM_VAR obj_name_[] = #obj_; \
03356         QS_CRIT_STAT_ \
03357         QS_CRIT_ENTRY_(); \
03358         QP_ QS::begin(static_cast<uint8_t>(QP_ QS_OBJ_DIC)); \
03359         QS_OBJ_(obj_); \
03360         QS_STR_ROM_(&obj_name_[0]); \
03361         QP_ QS::end(); \
03362         QS_CRIT_EXIT_(); \
03363         QP_ QS::onFlush(); \
03364     } \
03365 } while (false)
03366 
03367 /// \brief Output function dictionary record
03368 ///
03369 /// A function dictionary record associates the binary address of a function
03370 /// in the target's memory with the human-readable name of the function.
03371 ///
03372 /// Providing a function dictionary QS record can vastly improve readability
03373 /// of the QS log, because instead of dealing with cryptic machine addresses
03374 /// the QSpy host utility can display human-readable function names.
03375 ///
03376 /// The example from #QS_SIG_DICTIONARY shows the definition of a function
03377 /// dictionary.
03378 #define QS_FUN_DICTIONARY(fun_) do { \
03379     if (QS_GLB_FILTER_(QP_ QS_FUN_DIC)) { \
03380         static char_t const Q_ROM Q_ROM_VAR fun_name_[] = #fun_; \
03381         QS_CRIT_STAT_ \
03382         QS_CRIT_ENTRY_(); \
03383         QP_ QS::begin(static_cast<uint8_t>(QP_ QS_FUN_DIC)); \
03384         QS_FUN_(fun_); \
03385         QS_STR_ROM_(&fun_name_[0]); \
03386         QP_ QS::end(); \
03387         QS_CRIT_EXIT_(); \
03388         QP_ QS::onFlush(); \
03389     } \
03390 } while (false)
03391 
03392 /// \brief Output user QS rectord dictionary record
03393 ///
03394 /// A user QS record dictionary record associates the numerical value of a
03395 /// user record with the human-readable identifier.
03396 #define QS_USR_DICTIONARY(rec_) do { \
03397     if (QS_GLB_FILTER_(QP_ QS_USR_DIC)) { \
03398         static char_t const Q_ROM Q_ROM_VAR usr_name_[] = #rec_; \
03399         QS_CRIT_STAT_ \
03400         QS_CRIT_ENTRY_(); \
03401         QP_ QS::begin(static_cast<uint8_t>(QP_ QS_USR_DIC)); \
03402         QS_U8_(static_cast<uint8_t>(rec_)); \
03403         QS_STR_ROM_(&usr_name_[0]); \
03404         QP_ QS::end(); \
03405         QS_CRIT_EXIT_(); \
03406         QP_ QS::onFlush(); \
03407     } \
03408 } while (false)
03409 
03410 /// \brief Output the assertion violation
03411 #define QS_ASSERTION(module_, loc_) do { \
03412     QS_BEGIN_NOCRIT_(QP_ QS_ASSERT, \
03413         static_cast<void *>(0), static_cast<void *>(0)) \
03414         QS_TIME_(); \
03415         QS_U16_(static_cast<uint16_t>(loc_)); \
03416         QS_STR_ROM_(module_); \
03417     QS_END_NOCRIT_() \
03418     QP_ QS::onFlush(); \
03419 } while (false)
03420 
03421 /// \brief Flush the QS trace data to the host
03422 ///
03423 /// This macro invokes the QS::flush() platform-dependent callback function
03424 /// to flush the QS trace buffer to the host. The function typically
03425 /// busy-waits until all the data in the buffer is sent to the host.
03426 /// This is acceptable only in the initial transient.
03427 #define QS_FLUSH()   (QP_ QS::onFlush())
03428 
03429 /// \brief Output the critical section entry record
03430 #define QF_QS_CRIT_ENTRY() \
03431     QS_BEGIN_NOCRIT_(QP_ QS_QF_CRIT_ENTRY, \
03432         static_cast<void *>(0), static_cast<void *>(0)) \
03433         QS_TIME_(); \
03434         QS_U8_((uint8_t)(++QF_critNest_)); \
03435     QS_END_NOCRIT_()
03436 
03437 /// \brief Output the critical section exit record
03438 #define QF_QS_CRIT_EXIT() \
03439     QS_BEGIN_NOCRIT_(QP_ QS_QF_CRIT_EXIT, \
03440         static_cast<void *>(0), static_cast<void *>(0)) \
03441         QS_TIME_(); \
03442         QS_U8_((uint8_t)(QF_critNest_--)); \
03443     QS_END_NOCRIT_()
03444 
03445 /// \brief Output the interrupt entry record
03446 #define QF_QS_ISR_ENTRY(isrnest_, prio_) \
03447     QS_BEGIN_NOCRIT_(QP_ QS_QF_ISR_ENTRY, \
03448         static_cast<void *>(0), static_cast<void *>(0)) \
03449         QS_TIME_(); \
03450         QS_U8_(isrnest_); \
03451         QS_U8_(prio_); \
03452     QS_END_NOCRIT_()
03453 
03454 /// \brief Output the interrupt exit record
03455 #define QF_QS_ISR_EXIT(isrnest_, prio_) \
03456     QS_BEGIN_NOCRIT_(QP_ QS_QF_ISR_EXIT,  \
03457         static_cast<void *>(0), static_cast<void *>(0)) \
03458         QS_TIME_(); \
03459         QS_U8_(isrnest_); \
03460         QS_U8_(prio_); \
03461     QS_END_NOCRIT_()
03462 
03463 /// \brief Execute an action that is only necessary for QS output
03464 #define QF_QS_ACTION(act_)      (act_)
03465 
03466 #else                                                                 // Q_SPY
03467 
03468 // qs_dummy.h ================================================================
03469 /// \brief Dummy definitions of the QS macros that avoid code generation from
03470 /// the QS instrumentation.
03471 
03472 #define QS_INIT(arg_)                   (true)
03473 #define QS_EXIT()                       ((void)0)
03474 #define QS_DUMP()                       ((void)0)
03475 #define QS_RESET()                      ((void)0)
03476 #define QS_FILTER_ON(rec_)              ((void)0)
03477 #define QS_FILTER_OFF(rec_)             ((void)0)
03478 #define QS_FILTER_SM_OBJ(obj_)          ((void)0)
03479 #define QS_FILTER_AO_OBJ(obj_)          ((void)0)
03480 #define QS_FILTER_MP_OBJ(obj_)          ((void)0)
03481 #define QS_FILTER_EQ_OBJ(obj_)          ((void)0)
03482 #define QS_FILTER_TE_OBJ(obj_)          ((void)0)
03483 #define QS_FILTER_AP_OBJ(obj_)          ((void)0)
03484 
03485 #define QS_GET_BYTE(pByte_)             (static_cast<uint16_t>(0xFFFFU))
03486 #define QS_GET_BLOCK(pSize_)            (static_cast<uint8_t *>(0))
03487 
03488 #define QS_BEGIN(rec_, obj_)            if (false) {
03489 #define QS_END()                        }
03490 #define QS_BEGIN_NOCRIT(rec_, obj_)     if (false) {
03491 #define QS_END_NOCRIT()                 }
03492 
03493 #define QS_I8(width_, data_)            ((void)0)
03494 #define QS_U8(width_, data_)            ((void)0)
03495 #define QS_I16(width_, data_)           ((void)0)
03496 #define QS_U16(width_, data_)           ((void)0)
03497 #define QS_I32(width_, data_)           ((void)0)
03498 #define QS_U32(width_, data_)           ((void)0)
03499 #define QS_F32(width_, data_)           ((void)0)
03500 #define QS_F64(width_, data_)           ((void)0)
03501 #define QS_U64(width_, data_)           ((void)0)
03502 #define QS_STR(str_)                    ((void)0)
03503 #define QS_U32_HEX(width_, data_)       ((void)0)
03504 #define QS_STR_ROM(str_)                ((void)0)
03505 #define QS_MEM(mem_, size_)             ((void)0)
03506 #define QS_SIG(sig_, obj_)              ((void)0)
03507 #define QS_OBJ(obj_)                    ((void)0)
03508 #define QS_FUN(fun_)                    ((void)0)
03509 
03510 #define QS_SIG_DICTIONARY(sig_, obj_)   ((void)0)
03511 #define QS_OBJ_DICTIONARY(obj_)         ((void)0)
03512 #define QS_FUN_DICTIONARY(fun_)         ((void)0)
03513 #define QS_USR_DICTIONARY(rec_)         ((void)0)
03514 #define QS_ASSERTION(module_, loc_)     ((void)0)
03515 #define QS_FLUSH()                      ((void)0)
03516 
03517 // internal QS macros used only in the QP components .........................
03518 #define QS_CRIT_STAT_
03519 #define QS_BEGIN_(rec_, refObj_, obj_)  if (false) {
03520 #define QS_END_()                       }
03521 #define QS_BEGIN_NOCRIT_(rec_, refObj_, obj_) if (false) {
03522 #define QS_END_NOCRIT_()                }
03523 #define QS_U8_(data_)                   ((void)0)
03524 #define QS_U16_(data_)                  ((void)0)
03525 #define QS_U32_(data_)                  ((void)0)
03526 #define QS_U64_(data_)                  ((void)0)
03527 #define QS_TIME_()                      ((void)0)
03528 #define QS_SIG_(sig_)                   ((void)0)
03529 #define QS_EVS_(size_)                  ((void)0)
03530 #define QS_OBJ_(obj_)                   ((void)0)
03531 #define QS_FUN_(fun_)                   ((void)0)
03532 #define QS_EQC_(ctr_)                   ((void)0)
03533 #define QS_MPC_(ctr_)                   ((void)0)
03534 #define QS_MPS_(size_)                  ((void)0)
03535 #define QS_TEC_(ctr_)                   ((void)0)
03536 
03537 #define QF_QS_CRIT_ENTRY()              ((void)0)
03538 #define QF_QS_CRIT_EXIT()               ((void)0)
03539 #define QF_QS_ISR_ENTRY(isrnest_, prio_) ((void)0)
03540 #define QF_QS_ISR_EXIT(isrnest_, prio_) ((void)0)
03541 #define QF_QS_ACTION(act_)              ((void)0)
03542 
03543 #endif                                                                // Q_SPY
03544 
03545 // qassert.h =================================================================
03546 /* \brief Customizable QP assertions.
03547 *
03548 * Defines customizable and memory-efficient assertions applicable to
03549 * embedded systems. This header file can be used in C, C++, and mixed C/C++
03550 * programs.
03551 *
03552 * \note The preprocessor switch Q_NASSERT disables checking assertions.
03553 * In particular macros #Q_ASSERT, #Q_REQUIRE, #Q_ENSURE, #Q_INVARIANT,
03554 * #Q_ERROR as well as  #Q_ASSERT_ID, #Q_REQUIRE_ID, #Q_ENSURE_ID,
03555 * #Q_INVARIANT_ID, and #Q_ERROR_ID do NOT evaluate the test condition
03556 * passed as the argument to these macros. One notable exception is the
03557 * macro #Q_ALLEGE, that still evaluates the test condition, but does
03558 * not report assertion failures when the switch Q_NASSERT is defined.
03559 */
03560 #ifdef Q_NASSERT          /* Q_NASSERT defined--assertion checking disabled */
03561 
03562     #define Q_DEFINE_THIS_FILE
03563     #define Q_DEFINE_THIS_MODULE(name_)
03564     #define Q_ASSERT(test_)             ((void)0)
03565     #define Q_ASSERT_ID(id_, test_)     ((void)0)
03566     #define Q_ALLEGE(test_)             ((void)(test_))
03567     #define Q_ALLEGE_ID(id_, test_)     ((void)(test_))
03568     #define Q_ERROR()                   ((void)0)
03569     #define Q_ERROR_ID(id_)             ((void)0)
03570 
03571 #else                  /* Q_NASSERT not defined--assertion checking enabled */
03572 
03573     #ifdef __cplusplus
03574         extern "C" {
03575     #endif
03576 
03577     /** \brief Type for line numbers.
03578     *
03579     * This typedef specifies strong type for line numbers. The use of this
03580     * type, rather than plain 'int', is in compliance with the MISRA-C 2004
03581     * Rule 6.3(adv).
03582     */
03583     typedef int int_t;
03584 
03585     /** callback invoked in case the condition passed to #Q_ASSERT,
03586     * #Q_REQUIRE, #Q_ENSURE, #Q_ERROR, #Q_ALLEGE as well as #Q_ASSERT_ID,
03587     * #Q_REQUIRE_ID, #Q_ENSURE_ID, #Q_ERROR_ID, and #Q_ALLEGE_ID evaluates
03588     * to FALSE.
03589     *
03590     * \param file name where the assertion failed
03591     * \param line number at which the assertion failed
03592     */
03593     void Q_onAssert(char_t const Q_ROM * const Q_ROM_VAR file,
03594                     int_t const line);
03595 
03596     #ifdef __cplusplus
03597         }
03598     #endif
03599 
03600     /** Place this macro at the top of each C/C++ module to define the file
03601     * name string using __FILE__ (NOTE: __FILE__ might contain lengthy path
03602     * name). This file name will be used in reporting assertions in this file.
03603     */
03604     #define Q_DEFINE_THIS_FILE \
03605         static char_t const Q_ROM Q_ROM_VAR l_this_file[] = __FILE__;
03606 
03607     /** Place this macro at the top of each C/C++ module to define the module
03608     * name as the argument \a name_. This file name will be used in reporting
03609     * assertions in this file.
03610     */
03611     #define Q_DEFINE_THIS_MODULE(name_) \
03612         static char_t const Q_ROM Q_ROM_VAR l_this_file[] = name_;
03613 
03614     /** General purpose assertion that makes sure the \a test_ argument is
03615     * TRUE. Calls the Q_onAssert() callback if the \a test_ evaluates
03616     * to FALSE.
03617     * \note the \a test_ is NOT evaluated if assertions are disabled with
03618     * the Q_NASSERT switch.
03619     * \sa #Q_ASSERT_ID
03620     */
03621     #define Q_ASSERT(test_) \
03622         ((test_) ? (void)0 : Q_onAssert(&l_this_file[0], (int_t)__LINE__))
03623 
03624     /** General purpose assertion that makes sure the \a test_ argument is
03625     * TRUE. Calls the Q_onAssert() callback if the \a test_ evaluates
03626     * to FALSE. The argument \a id_ is the ID number (unique within
03627     * the file) of the assertion. This assertion style is better suited
03628     * for unit testig, because it avoids the volatility of line numbers
03629     * for indentifying assertions.
03630     * \note the \a test_ is NOT evaluated if assertions are disabled with
03631     * the Q_NASSERT switch.
03632     * \sa #Q_ASSERT
03633     */
03634     #define Q_ASSERT_ID(id_, test_) \
03635         ((test_) ? (void)0 : Q_onAssert(&l_this_file[0], (int_t)(id_))
03636 
03637     /** General purpose assertion that ALWAYS evaluates the \a test_
03638     * argument and calls the Q_onAssert() callback if the \a test_
03639     * evaluates to FALSE.
03640     * \note the \a test_ argument IS always evaluated even when assertions
03641     * are disabled with the Q_NASSERT macro. When the Q_NASSERT macro is
03642     * defined, the Q_onAssert() callback is NOT called, even if the
03643     * \a test_ evaluates to FALSE.
03644     * \sa #Q_ALLEGE_ID
03645     */
03646     #define Q_ALLEGE(test_)    Q_ASSERT(test_)
03647 
03648     /** General purpose assertion that ALWAYS evaluates the \a test_
03649     * argument and calls the Q_onAssert() callback if the \a test_
03650     * evaluates to FALSE. This assertion style is better suited
03651     * for unit testig, because it avoids the volatility of line numbers
03652     * for indentifying assertions.
03653     * \note the \a test_ argument IS always evaluated even when assertions
03654     * are disabled with the Q_NASSERT macro. When the Q_NASSERT macro is
03655     * defined, the Q_onAssert() callback is NOT called, even if the
03656     * \a test_ evaluates to FALSE.
03657     * \sa #Q_ALLEGE
03658     */
03659     #define Q_ALLEGE_ID(id_, test_) Q_ASSERT_ID(id_, test_)
03660 
03661     /** Assertion that always calls the Q_onAssert() callback if
03662     * ever executed.
03663     * \note can be disabled with the Q_NASSERT switch.
03664     * \sa #Q_ERROR_ID
03665     */
03666     #define Q_ERROR() \
03667         Q_onAssert(&l_this_file[0], (int_t)__LINE__)
03668 
03669     /** Assertion that always calls the Q_onAssert() callback if
03670     * ever executed. This assertion style is better suited for unit
03671     * testig, because it avoids the volatility of line numbers for
03672     * indentifying assertions.
03673     * \note can be disabled with the Q_NASSERT switch.
03674     * \sa #Q_ERROR
03675     */
03676     #define Q_ERROR_ID(id_) \
03677         Q_onAssert(l_this_file, (int_t)(id_))
03678 
03679 #endif                                                         /* Q_NASSERT */
03680 
03681 /** Assertion that checks for a precondition. This macro is equivalent to
03682 * #Q_ASSERT, except the name provides a better documentation of the
03683 * intention of this assertion.
03684 * \sa #Q_REQUIRE_ID
03685 */
03686 #define Q_REQUIRE(test_)         Q_ASSERT(test_)
03687 
03688 /** Assertion that checks for a precondition. This macro is equivalent to
03689 * #Q_ASSERT_ID, except the name provides a better documentation of the
03690 * intention of this assertion.
03691 * \sa #Q_REQUIRE
03692 */
03693 #define Q_REQUIRE_ID(id_, test_) Q_ASSERT_ID(id_, test_)
03694 
03695 /** Assertion that checks for a postcondition. This macro is equivalent to
03696 * #Q_ASSERT, except the name provides a better documentation of the
03697 * intention of this assertion.
03698 * \sa #Q_ENSURE_ID
03699 */
03700 #define Q_ENSURE(test_)          Q_ASSERT(test_)
03701 
03702 /** Assertion that checks for a postcondition. This macro is equivalent to
03703 * #Q_ASSERT_ID, except the name provides a better documentation of the
03704 * intention of this assertion.
03705 * \sa #Q_ENSURE
03706 */
03707 #define Q_ENSURE_ID(id_, test_)  Q_ASSERT_ID(id_, test_)
03708 
03709 /** Assertion that checks for an invariant. This macro is equivalent to
03710 * #Q_ASSERT, except the name provides a better documentation of the
03711 * intention of this assertion.
03712 * \sa #Q_INVARIANT_ID
03713 */
03714 #define Q_INVARIANT(test_)       Q_ASSERT(test_)
03715 
03716 /** Assertion that checks for an invariant. This macro is equivalent to
03717 * #Q_ASSERT_ID, except the name provides a better documentation of the
03718 * intention of this assertion.
03719 * \sa #Q_INVARIANT
03720 */
03721 #define Q_INVARIANT_ID(id_, test_) Q_ASSERT_ID(id_, test_)
03722 
03723 /** Compile-time assertion exploits the fact that in C/C++ a dimension of
03724 * an array cannot be negative. The following declaration causes a compilation
03725 * error if the compile-time expression (\a test_) is not TRUE. The assertion
03726 * has no runtime side effects.
03727 */
03728 #define Q_ASSERT_COMPILE(test_) \
03729     extern int_t Q_assert_compile[(test_) ? 1 : -1]
03730 
03731 #endif                                                                 // qp_h