QP/C++
Classes | Defines | Typedefs | Enumerations | Variables
qs.h File Reference

QS/C++ platform-independent public interface. This header file must be included directly or indirectly in all modules (*.cpp files) that use QS/C++. More...

Go to the source code of this file.

Classes

class  QS
 Quantum Spy logging facilities. More...

Defines

#define QS_TIME_SIZE   4
 The size (in bytes) of the QS time stamp. Valid values: 1, 2, or 4; default 4.
#define QS_TIME_()   (QP_ QS::u32_(QP_ QS::onGetTime()))
 Internal macro to output time stamp to the QS record.
#define QS_INIT(arg_)   (QP_ QS::onStartup(arg_))
 Initialize the QS facility.
#define QS_EXIT()   (QP_ QS::onCleanup())
 Cleanup the QS facility.
#define QS_FILTER_ON(rec_)   (QP_ QS::filterOn(static_cast<uint8_t>(rec_)))
 Global Filter ON for a given record type rec.
#define QS_FILTER_OFF(rec_)   (QP_ QS::filterOff(static_cast<uint8_t>(rec_)))
 Global filter OFF for a given record type rec.
#define QS_FILTER_SM_OBJ(obj_)   (QP_ QS::smObj_ = (obj_))
 Local Filter for a given state machine object obj_.
#define QS_FILTER_AO_OBJ(obj_)   (QP_ QS::aoObj_ = (obj_))
 Local Filter for a given active object obj_.
#define QS_FILTER_MP_OBJ(obj_)   (QP_ QS::mpObj_ = (obj_))
 Local Filter for a given memory pool object obj_.
#define QS_FILTER_EQ_OBJ(obj_)   (QP_ QS::eqObj_ = (obj_))
 Filter for a given event queue object obj_.
#define QS_FILTER_TE_OBJ(obj_)   (QP_ QS::teObj_ = (obj_))
 Local Filter for a given time event object obj_.
#define QS_FILTER_AP_OBJ(obj_)   (QP_ QS::apObj_ = (obj_))
 Local Filter for a generic application object obj_.
#define QS_BEGIN_NOCRIT(rec_, obj_)
 Begin a QS user record without entering critical section.
#define QS_END_NOCRIT()   QS_END_NOCRIT_()
 End a QS user record without exiting critical section.
#define QS_CRIT_STAT_
 This is an internal macro for defining the critical section status type.
#define QS_CRIT_ENTRY_()   QF_CRIT_ENTRY(dummy)
 This is an internal macro for entering a critical section.
#define QS_CRIT_EXIT_()   QF_CRIT_EXIT(dummy)
 This is an internal macro for exiting a critical section.
#define QS_BEGIN(rec_, obj_)
 Begin a user QS record with entering critical section.
#define QS_END()   QS_END_()
 End a QS record with exiting critical section.
#define QS_BEGIN_(rec_, objFilter_, obj_)
 Internal QS macro to begin a QS record with entering critical section.
#define QS_END_()
 Internal QS macro to end a QS record with exiting critical section.
#define QS_BEGIN_NOCRIT_(rec_, objFilter_, obj_)
 Internal QS macro to begin a QS record without entering critical section.
#define QS_END_NOCRIT_()
 Internal QS macro to end a QS record without exiting critical section.
#define QS_U8_(data_)   (QP_ QS::u8_(data_))
 Internal QS macro to output an unformatted uint8_t data element.
#define QS_U16_(data_)   (QP_ QS::u16_(data_))
 Internal QS macro to output an unformatted uint16_t data element.
#define QS_U32_(data_)   (QP_ QS::u32_(data_))
 Internal QS macro to output an unformatted uint32_t data element.
#define QS_OBJ_(obj_)   (QP_ QS::u32_(reinterpret_cast<uint32_t>(obj_)))
 Internal QS macro to output an unformatted object pointer data element.
#define QS_FUN_(fun_)   (QP_ QS::u32_(reinterpret_cast<uint32_t>(fun_)))
 Internal QS macro to output an unformatted function pointer data element.
#define QS_STR_(msg_)   (QP_ QS::str_(msg_))
 Internal QS macro to output a zero-terminated ASCII string data element.
#define QS_STR_ROM_(msg_)   (QP_ QS::str_ROM_(msg_))
 Internal QS macro to output a zero-terminated ASCII string allocated in ROM data element.
#define QS_I8(width_, data_)
 Output formatted int8_t to the QS record.
#define QS_U8(width_, data_)
 Output formatted uint8_t to the QS record.
#define QS_I16(width_, data_)
 Output formatted int16_t to the QS record.
#define QS_U16(width_, data_)
 Output formatted uint16_t to the QS record.
#define QS_I32(width_, data_)
 Output formatted int32_t to the QS record.
#define QS_U32(width_, data_)
 Output formatted uint32_t to the QS record.
#define QS_F32(width_, data_)
 Output formatted 32-bit floating point number to the QS record.
#define QS_F64(width_, data_)
 Output formatted 64-bit floating point number to the QS record.
#define QS_I64(width_, data_)
 Output formatted int64_t to the QS record.
#define QS_U64(width_, data_)
 Output formatted uint64_t to the QS record.
#define QS_U32_HEX(width_, data_)
 Output formatted uint32_t to the QS record.
#define QS_STR(str_)   (QP_ QS::str(str_))
 Output formatted zero-terminated ASCII string to the QS record.
#define QS_STR_ROM(str_)   (QP_ QS::str_ROM(str_))
 Output formatted zero-terminated ASCII string from ROM to the QS record.
#define QS_MEM(mem_, size_)   (QP_ QS::mem((mem_), (size_)))
 Output formatted memory block of up to 255 bytes to the QS record.
#define QS_OBJ(obj_)   (QP_ QS::u32(QS_OBJ_T, (uint32_t)(obj_)))
 Output formatted object pointer to the QS record.
#define QS_FUN(fun_)   (QP_ QS::u32(QS_FUN_T, (uint32_t)(fun_)))
 Output formatted function pointer to the QS record.
#define QS_RESET()
 Reset the QS session.
#define QS_SIG_DICTIONARY(sig_, obj_)
 Output signal dictionary record.
#define QS_OBJ_DICTIONARY(obj_)
 Output object dictionary record.
#define QS_FUN_DICTIONARY(fun_)
 Output function dictionary record.
#define QS_USR_DICTIONARY(rec_)
 Output user QS record dictionary record.
#define QS_ASSERTION(module_, loc_)
 Output the assertion violation.
#define QS_FLUSH()   (QP_ QS::onFlush())
 Flush the QS trace data to the host.
#define QF_QS_CRIT_ENTRY()
 Output the critical section entry record.
#define QF_QS_CRIT_EXIT()
 Output the critical section exit record.
#define QF_QS_ISR_ENTRY(isrnest_, prio_)
 Output the interrupt entry record.
#define QF_QS_ISR_EXIT(isrnest_, prio_)
 Output the interrupt exit record.
#define QF_QS_ACTION(act_)   (act_)
 Execute an action that is only necessary for QS output.

Typedefs

typedef uint32_t QSTimeCtr
 The type of the QS time stamp.

Enumerations

enum  QSpyRecords {
  QS_QP_RESET, QS_QEP_STATE_ENTRY, QS_QEP_STATE_EXIT, QS_QEP_STATE_INIT,
  QS_QEP_INIT_TRAN, QS_QEP_INTERN_TRAN, QS_QEP_TRAN, QS_QEP_IGNORED,
  QS_QEP_DISPATCH, QS_QEP_UNHANDLED, QS_QF_ACTIVE_ADD, QS_QF_ACTIVE_REMOVE,
  QS_QF_ACTIVE_SUBSCRIBE, QS_QF_ACTIVE_UNSUBSCRIBE, QS_QF_ACTIVE_POST_FIFO, QS_QF_ACTIVE_POST_LIFO,
  QS_QF_ACTIVE_GET, QS_QF_ACTIVE_GET_LAST, QS_QF_EQUEUE_INIT, QS_QF_EQUEUE_POST_FIFO,
  QS_QF_EQUEUE_POST_LIFO, QS_QF_EQUEUE_GET, QS_QF_EQUEUE_GET_LAST, QS_QF_MPOOL_INIT,
  QS_QF_MPOOL_GET, QS_QF_MPOOL_PUT, QS_QF_PUBLISH , QS_QF_NEW,
  QS_QF_GC_ATTEMPT, QS_QF_GC, QS_QF_TICK, QS_QF_TIMEEVT_ARM,
  QS_QF_TIMEEVT_AUTO_DISARM, QS_QF_TIMEEVT_DISARM_ATTEMPT, QS_QF_TIMEEVT_DISARM, QS_QF_TIMEEVT_REARM,
  QS_QF_TIMEEVT_POST, QS_QF_TIMEEVT_CTR, QS_QF_CRIT_ENTRY, QS_QF_CRIT_EXIT,
  QS_QF_ISR_ENTRY, QS_QF_ISR_EXIT, QS_QF_INT_DISABLE, QS_QF_INT_ENABLE ,
  QS_QK_MUTEX_LOCK, QS_QK_MUTEX_UNLOCK, QS_QK_SCHEDULE , QS_SIG_DIC,
  QS_OBJ_DIC, QS_FUN_DIC, QS_USR_DIC , QS_ASSERT,
  QS_USER
}
 Quantum Spy record types. More...
enum  QSType {
  QS_I8_T, QS_U8_T, QS_I16_T, QS_U16_T,
  QS_I32_T, QS_U32_T, QS_F32_T, QS_F64_T,
  QS_STR_T, QS_MEM_T, QS_SIG_T, QS_OBJ_T,
  QS_FUN_T, QS_I64_T, QS_U64_T, QS_U32_HEX_T
}
 Enumerates data formats recognized by QS. More...

Variables

uint8_t const QS_ALL_RECORDS = static_cast<uint8_t>(0xFF)
 Specification of all QS records for the QS::filterOn() and QS::filterOff()
uint16_t const QS_EOD = static_cast<uint16_t>(0xFFFF)
 Constant representing End-Of-Data condition returned from the QS::getByte() function.
uint8_t QF_critNest_
 critical section nesting level

Detailed Description

QS/C++ platform-independent public interface. This header file must be included directly or indirectly in all modules (*.cpp files) that use QS/C++.

Definition in file qs.h.


Define Documentation

#define QS_BEGIN (   rec_,
  obj_ 
)
Value:
if (QS_GLB_FILTER_(rec_) \
        && ((QP_ QS::apObj_ == static_cast<void *>(0)) \
            || (QP_ QS::apObj_ == (obj_)))) \
    { \
        QS_CRIT_STAT_ \
        QS_CRIT_ENTRY_(); \
        QP_ QS::begin(static_cast<uint8_t>(rec_)); \
        QS_TIME_();

Begin a user QS record with entering critical section.

The following example shows how to build a user QS record using the macros QS_BEGIN, QS_END, and the formatted output macros: QS_U8 and QS_STR.

enum UserSpyRecords {
    QS_QDPP_DISPLAY = QS_USER                      // define user record types
    . . .
};

void displyPhilStat(uint8_t n, char const *stat) {
    . . .

    QS_BEGIN(QS_QDPP_DISPLAY);                      // output a user QS record
        QS_U8(1, n);
        QS_STR(stat);
    QS_END();
}
Note:
Must always be used in pair with QS_END

Definition at line 710 of file qs.h.

#define QS_BEGIN_ (   rec_,
  objFilter_,
  obj_ 
)
Value:
if (QS_GLB_FILTER_(rec_) \
        && (((objFilter_) == static_cast<void *>(0)) \
            || ((objFilter_) == (obj_)))) \
    { \
        QS_CRIT_ENTRY_(); \
        QP_ QS::begin(static_cast<uint8_t>(rec_));

Internal QS macro to begin a QS record with entering critical section.

Note:
This macro is intended to use only inside QP components and NOT at the application level.
See also:
QS_BEGIN

Definition at line 734 of file qs.h.

Referenced by QFsm::dispatch(), QHsm::dispatch(), QMPool::init(), QFsm::init(), QEQueue::init(), QHsm::init(), and QF::new_().

#define QS_BEGIN_NOCRIT_ (   rec_,
  objFilter_,
  obj_ 
)
Value:
if (QS_GLB_FILTER_(rec_) \
        && (((objFilter_) == static_cast<void *>(0)) \
            || ((objFilter_) == (obj_)))) \
    { \
        QP_ QS::begin(static_cast<uint8_t>(rec_));

Internal QS macro to begin a QS record without entering critical section.

Note:
This macro is intended to use only inside QP components and NOT at the application level.
See also:
QS_BEGIN_NOCRIT

Definition at line 755 of file qs.h.

Referenced by QTimeEvt::ctr(), QTimeEvt::disarm(), QF::gc(), QMPool::get(), QEQueue::get(), QK::mutexLock(), QK::mutexUnlock(), QEQueue::postFIFO(), QActive::postFIFO(), QEQueue::postLIFO(), QActive::postLIFO(), QF::publish(), QMPool::put(), QK_sched_(), QK_schedExt_(), QTimeEvt::rearm(), QF::remove_(), QActive::subscribe(), QF::tick(), QActive::unsubscribe(), and QActive::unsubscribeAll().

#define QS_CRIT_ENTRY_ ( )    QF_CRIT_ENTRY(dummy)

This is an internal macro for entering a critical section.

The purpose of this macro is to enable writing the same code for the case when critical section status type is defined and when it is not. If the macro QF_CRIT_STAT_TYPE is defined, this internal macro invokes QF_CRIT_ENTRY passing the key variable as the parameter. Otherwise QF_CRIT_ENTRY is invoked with a dummy parameter.

See also:
QF_CRIT_ENTRY

Definition at line 684 of file qs.h.

#define QS_CRIT_EXIT_ ( )    QF_CRIT_EXIT(dummy)

This is an internal macro for exiting a critical section.

The purpose of this macro is to enable writing the same code for the case when critical section status type is defined and when it is not. If the macro QF_CRIT_STAT_TYPE is defined, this internal macro invokes QF_CRIT_EXIT passing the key variable as the parameter. Otherwise QF_CRIT_EXIT is invoked with a dummy parameter.

See also:
QF_CRIT_EXIT

Definition at line 695 of file qs.h.

#define QS_CRIT_STAT_

This is an internal macro for defining the critical section status type.

The purpose of this macro is to enable writing the same code for the case when critical section status type is defined and when it is not. If the macro QF_CRIT_STAT_TYPE is defined, this internal macro provides the definition of the critical section status variable. Otherwise this macro is empty.

See also:
QF_CRIT_STAT_TYPE

Definition at line 673 of file qs.h.

Referenced by QFsm::dispatch(), QHsm::dispatch(), QMPool::init(), QFsm::init(), QEQueue::init(), QHsm::init(), and QF::new_().

#define QS_END ( )    QS_END_()

End a QS record with exiting critical section.

See also:
example for QS_BEGIN
Note:
Must always be used in pair with QS_BEGIN

Definition at line 723 of file qs.h.

#define QS_END_ ( )
Value:
QP_ QS::end(); \
        QS_CRIT_EXIT_(); \
    }

Internal QS macro to end a QS record with exiting critical section.

Note:
This macro is intended to use only inside QP components and NOT at the application level.
See also:
QS_END

Definition at line 746 of file qs.h.

Referenced by QFsm::dispatch(), QHsm::dispatch(), QMPool::init(), QFsm::init(), QEQueue::init(), QHsm::init(), and QF::new_().

#define QS_END_NOCRIT_ ( )
Value:
QP_ QS::end(); \
    }

Internal QS macro to end a QS record without exiting critical section.

Note:
This macro is intended to use only inside QP components and NOT at the application level.
See also:
QS_END_NOCRIT

Definition at line 766 of file qs.h.

Referenced by QTimeEvt::ctr(), QTimeEvt::disarm(), QF::gc(), QMPool::get(), QEQueue::get(), QK::mutexLock(), QK::mutexUnlock(), QEQueue::postFIFO(), QActive::postFIFO(), QEQueue::postLIFO(), QActive::postLIFO(), QF::publish(), QMPool::put(), QK_sched_(), QK_schedExt_(), QTimeEvt::rearm(), QF::remove_(), QActive::subscribe(), QF::tick(), QActive::unsubscribe(), and QActive::unsubscribeAll().

#define QS_EXIT ( )    (QP_ QS::onCleanup())

Cleanup the QS facility.

This macro provides an indirection layer to invoke the QS cleanup routine if #Q_SPY is defined, or do nothing if #Q_SPY is not defined.

See also:
QS::onCleanup()

Definition at line 505 of file qs.h.

#define QS_FILTER_AO_OBJ (   obj_)    (QP_ QS::aoObj_ = (obj_))

Local Filter for a given active object obj_.

This macro sets up the active object local filter if #Q_SPY is defined, or does nothing if #Q_SPY is not defined. The argument obj_ is the pointer to the active object that you want to monitor.

The active object filter allows you to filter QS records pertaining only to a given active object. With this filter disabled, QS will output records from all active objects in your application. The object filter is disabled by setting the active object pointer obj_ to NULL.

The active object filter affects the following QS records: QS_QF_ACTIVE_ADD, QS_QF_ACTIVE_REMOVE, QS_QF_ACTIVE_SUBSCRIBE, QS_QF_ACTIVE_UNSUBSCRIBE, QS_QF_ACTIVE_POST_FIFO, QS_QF_ACTIVE_POST_LIFO, QS_QF_ACTIVE_GET, and QS_QF_ACTIVE_GET_LAST.

See also:
Example of using QS filters in QS_FILTER_ON documentation

Definition at line 566 of file qs.h.

#define QS_FILTER_AP_OBJ (   obj_)    (QP_ QS::apObj_ = (obj_))

Local Filter for a generic application object obj_.

This macro sets up the local application object filter if #Q_SPY is defined, or does nothing if #Q_SPY is not defined. The argument obj_ is the pointer to the application object you want to monitor.

The application object filter allows you to filter QS records pertaining only to a given application object. With this filter disabled, QS will output records from all application-records enabled by the global filter. The local filter is disabled by setting the time event pointer obj_ to NULL.

See also:
Example of using QS filters in QS_FILTER_ON documentation

Definition at line 636 of file qs.h.

#define QS_FILTER_EQ_OBJ (   obj_)    (QP_ QS::eqObj_ = (obj_))

Filter for a given event queue object obj_.

This macro sets up the event queue object filter if #Q_SPY is defined, or does nothing if #Q_SPY is not defined. The argument obj_ is the pointer to the "raw" thread-safe queue object you want to monitor.

The event queue filter allows you to filter QS records pertaining only to a given event queue. With this filter disabled, QS will output records from all event queues in your application. The object filter is disabled by setting the event queue pointer obj_ to NULL.

The event queue filter affects the following QS records: QS_QF_EQUEUE_INIT, QS_QF_EQUEUE_POST_FIFO, QS_QF_EQUEUE_POST_LIFO, QS_QF_EQUEUE_GET, and QS_QF_EQUEUE_GET_LAST.

See also:
Example of using QS filters in #QS_FILTER_IN documentation

Definition at line 602 of file qs.h.

#define QS_FILTER_MP_OBJ (   obj_)    (QP_ QS::mpObj_ = (obj_))

Local Filter for a given memory pool object obj_.

This macro sets up the memory pool object local filter if #Q_SPY is defined, or does nothing if #Q_SPY is not defined. The argument obj_ is the pointer to the memory buffer used during the initialization of the event pool with QF::poolInit().

The memory pool filter allows you to filter QS records pertaining only to a given memory pool. With this filter disabled, QS will output records from all memory pools in your application. The object filter is disabled by setting the memory pool pointer obj_ to NULL.

The memory pool filter affects the following QS records: QS_QF_MPOOL_INIT, QS_QF_MPOOL_GET, and QS_QF_MPOOL_PUT.

See also:
Example of using QS filters in QS_FILTER_ON documentation

Definition at line 584 of file qs.h.

#define QS_FILTER_OFF (   rec_)    (QP_ QS::filterOff(static_cast<uint8_t>(rec_)))

Global filter OFF for a given record type rec.

This macro provides an indirection layer to call QS::filterOff() if #Q_SPY is defined, or do nothing if #Q_SPY is not defined.

See also:
Example of using QS filters in QS_FILTER_ON documentation

Definition at line 522 of file qs.h.

#define QS_FILTER_ON (   rec_)    (QP_ QS::filterOn(static_cast<uint8_t>(rec_)))

Global Filter ON for a given record type rec.

This macro provides an indirection layer to call QS::filterOn() if #Q_SPY is defined, or do nothing if #Q_SPY is not defined.

The following example shows how to use QS filters:

main () {
    . . .

    if (!QS_INIT("1")) {                      // Initialize QSpy to use UART 1
        return -1;                                // Unable to initialize QSpy
    }
    QS_FILTER_IN(QS_ALL_RECORDS);        // start with enabling all QS records

    QS_FILTER_OUT(QS_QK_INT_LOCK);         // disable QS output of this record
    QS_FILTER_OUT(QS_QK_INT_UNLOCK);       // disable QS output of this record
    QS_FILTER_OUT(QS_QK_ISR_ENTRY);        // disable QS output of this record
    QS_FILTER_OUT(QS_QK_ISR_EXIT);         // disable QS output of this record

    QS_FILTER_SM_OBJ(&philo[3]);       // trace only this state machine object

    QS_FILTER_AO_OBJ(&philo[3]);              // trace only this active object

    QS_FILTER_MP_OBJ(regSizePoolSto);            // trace only this event pool

    QS_FILTER_EQ_OBJ(&rawQueue);                // trace only this event queue

    QS_FILTER_TE_OBJ(&philo[3].timeEvt__);       // trace only this time event

    . . .
}

Definition at line 514 of file qs.h.

#define QS_FILTER_SM_OBJ (   obj_)    (QP_ QS::smObj_ = (obj_))

Local Filter for a given state machine object obj_.

This macro sets up the state machine object local filter if #Q_SPY is defined, or does nothing if #Q_SPY is not defined. The argument obj_ is the pointer to the state machine object that you want to monitor.

The state machine object filter allows you to filter QS records pertaining only to a given state machine object. With this filter disabled, QS will output records from all state machines in your application. The object filter is disabled by setting the state machine pointer to NULL.

The state machine filter affects the following QS records: QS_QEP_STATE_ENTRY, QS_QEP_STATE_EXIT, QS_QEP_STATE_INIT, QS_QEP_INIT_TRAN, QS_QEP_INTERN_TRAN, QS_QEP_TRAN, and QS_QEP_IGNORED.

Note:
Because active objects are state machines at the same time, the state machine filter (QS_FILTER_SM_OBJ) pertains to active objects as well. However, the state machine filter is more general, because it can be used only for state machines that are not active objects, such as "Orthogonal Components".
See also:
Example of using QS filters in QS_FILTER_ON documentation

Definition at line 547 of file qs.h.

#define QS_FILTER_TE_OBJ (   obj_)    (QP_ QS::teObj_ = (obj_))

Local Filter for a given time event object obj_.

This macro sets up the time event object local filter if #Q_SPY is defined, or does nothing if #Q_SPY is not defined. The argument obj_ is the pointer to the time event object you want to monitor.

The time event filter allows you to filter QS records pertaining only to a given time event. With this filter disabled, QS will output records from all time events in your application. The object filter is disabled by setting the time event pointer obj_ to NULL.

The time event filter affects the following QS records: QS_QF_TIMEEVT_ARM, QS_QF_TIMEEVT_AUTO_DISARM, QS_QF_TIMEEVT_DISARM_ATTEMPT, QS_QF_TIMEEVT_DISARM, QS_QF_TIMEEVT_REARM, QS_QF_TIMEEVT_POST, and ::QS_QF_TIMEEVT_PUBLISH.

See also:
Example of using QS filters in QS_FILTER_ON documentation

Definition at line 621 of file qs.h.

#define QS_FLUSH ( )    (QP_ QS::onFlush())

Flush the QS trace data to the host.

This macro invokes the QS::flush() platform-dependent callback function to flush the QS trace buffer to the host. The function typically busy-waits until all the data in the buffer is sent to the host. This is acceptable only in the initial transient.

Definition at line 1087 of file qs.h.

Referenced by QActive::start().

#define QS_FUN_ (   fun_)    (QP_ QS::u32_(reinterpret_cast<uint32_t>(fun_)))

Internal QS macro to output an unformatted function pointer data element.

Note:
the size of the pointer depends on the macro #QS_FUN_PTR_SIZE. If the size is not defined the size of pointer is assumed 4-bytes.

Definition at line 823 of file qs.h.

Referenced by QFsm::dispatch(), QHsm::dispatch(), QFsm::init(), and QHsm::init().

#define QS_FUN_DICTIONARY (   fun_)
Value:
do { \
    if (QS_GLB_FILTER_(QP_ QS_FUN_DIC)) { \
        static char_t const Q_ROM Q_ROM_VAR fun_name_[] = #fun_; \
        QS_CRIT_STAT_ \
        QS_CRIT_ENTRY_(); \
        QP_ QS::begin(static_cast<uint8_t>(QP_ QS_FUN_DIC)); \
        QS_FUN_(fun_); \
        QS_STR_ROM_(&fun_name_[0]); \
        QP_ QS::end(); \
        QS_CRIT_EXIT_(); \
        QP_ QS::onFlush(); \
    } \
} while (false)

Output function dictionary record.

A function dictionary record associates the binary address of a function in the target's memory with the human-readable name of the function.

Providing a function dictionary QS record can vastly improve readability of the QS log, because instead of dealing with cryptic machine addresses the QSpy host utility can display human-readable function names.

The example from QS_SIG_DICTIONARY shows the definition of a function dictionary.

Definition at line 1038 of file qs.h.

#define QS_INIT (   arg_)    (QP_ QS::onStartup(arg_))

Initialize the QS facility.

This macro provides an indirection layer to invoke the QS initialization routine if #Q_SPY is defined, or do nothing if #Q_SPY is not defined.

See also:
QS::onStartup(), example of setting up a QS filter in #QS_FILTER_IN

Definition at line 498 of file qs.h.

#define QS_OBJ_ (   obj_)    (QP_ QS::u32_(reinterpret_cast<uint32_t>(obj_)))

Internal QS macro to output an unformatted object pointer data element.

Note:
the size of the pointer depends on the macro #QS_OBJ_PTR_SIZE. If the size is not defined the size of pointer is assumed 4-bytes.

Definition at line 805 of file qs.h.

Referenced by QTimeEvt::ctr(), QTimeEvt::disarm(), QFsm::dispatch(), QHsm::dispatch(), QMPool::get(), QEQueue::get(), QMPool::init(), QFsm::init(), QEQueue::init(), QHsm::init(), QEQueue::postFIFO(), QActive::postFIFO(), QEQueue::postLIFO(), QActive::postLIFO(), QF::publish(), QMPool::put(), QTimeEvt::rearm(), QF::remove_(), QActive::subscribe(), QF::tick(), QActive::unsubscribe(), and QActive::unsubscribeAll().

#define QS_OBJ_DICTIONARY (   obj_)
Value:
do { \
    if (QS_GLB_FILTER_(QP_ QS_OBJ_DIC)) { \
        static char_t const Q_ROM Q_ROM_VAR obj_name_[] = #obj_; \
        QS_CRIT_STAT_ \
        QS_CRIT_ENTRY_(); \
        QP_ QS::begin(static_cast<uint8_t>(QP_ QS_OBJ_DIC)); \
        QS_OBJ_(obj_); \
        QS_STR_ROM_(&obj_name_[0]); \
        QP_ QS::end(); \
        QS_CRIT_EXIT_(); \
        QP_ QS::onFlush(); \
    } \
} while (false)

Output object dictionary record.

An object dictionary record associates the binary address of an object in the target's memory with the human-readable name of the object.

Providing an object dictionary QS record can vastly improve readability of the QS log, because instead of dealing with cryptic machine addresses the QSpy host utility can display human-readable object names.

The following example shows the definition of object dictionary entry for the Table active object:

void tableStart(uint8_t prio,
                QEvent const *qSto[], uint32_t qLen,
                void *stkSto, uint32_t stkSize)
{
    static Table table;

    QS_OBJ_DICTIONARY(table);           // provide object dictionary for table

    table.start(prio,
                qSto, qLen, stkSto, stkSize,
                (QEvent *)0);
}

Definition at line 1013 of file qs.h.

#define QS_RESET ( )
Value:
do { \
    if (QS_GLB_FILTER_(QP_ QS_QP_RESET)) { \
        QS_CRIT_STAT_ \
        QS_CRIT_ENTRY_(); \
        QP_ QS::begin(static_cast<uint8_t>(QP_ QS_QP_RESET)); \
        QP_ QS::end(); \
        QS_CRIT_EXIT_(); \
        QP_ QS::onFlush(); \
    } \
} while (false)

Reset the QS session.

This trace record should be generated at the beginning of the QS session. It informs the QSPY host application that the new session has been started.

Definition at line 936 of file qs.h.

#define QS_SIG_DICTIONARY (   sig_,
  obj_ 
)
Value:
do { \
    if (QS_GLB_FILTER_(QP_ QS_SIG_DIC)) { \
        static char_t const Q_ROM Q_ROM_VAR sig_name_[] = #sig_; \
        QS_CRIT_STAT_ \
        QS_CRIT_ENTRY_(); \
        QP_ QS::begin(static_cast<uint8_t>(QP_ QS_SIG_DIC)); \
        QS_SIG_(sig_); \
        QS_OBJ_(obj_); \
        QS_STR_ROM_(&sig_name_[0]); \
        QP_ QS::end(); \
        QS_CRIT_EXIT_(); \
        QP_ QS::onFlush(); \
    } \
} while (false)

Output signal dictionary record.

A signal dictionary record associates the numerical value of the signal and the binary address of the state machine that consumes that signal with the human-readable name of the signal.

Providing a signal dictionary QS record can vastly improve readability of the QS log, because instead of dealing with cryptic machine addresses the QSpy host utility can display human-readable names.

A signal dictionary entry is associated with both the signal value sig_ and the state machine obj_, because signals are required to be unique only within a given state machine and therefore the same numerical values can represent different signals in different state machines.

For the "global" signals that have the same meaning in all state machines (such as globally published signals), you can specify a signal dictionary entry with the obj_ parameter set to NULL.

The following example shows the definition of signal dictionary entries in the initial transition of the Table active object. Please note that signals HUNGRY_SIG and DONE_SIG are associated with the Table state machine only ("me" obj_ pointer). The EAT_SIG signal, on the other hand, is global (0 obj_ pointer):

QState Table::initial(Table *me, QEvent const *) {
    uint8_t n;

    QS_SIG_DICTIONARY(HUNGRY_SIG, me);   // output signal dictionary QS record
    QS_SIG_DICTIONARY(DONE_SIG, me);     // output signal dictionary QS record
    QS_SIG_DICTIONARY(EAT_SIG, 0);       // output signal dictionary QS record

    QS_FUN_DICTIONARY(Table::serving);

    subscribe(HUNGRY_SIG);
    subscribe(DONE_SIG);
    subscribe(TERMINATE_SIG);

    for (n = 0; n < N; ++n) {
        me->fork__[n] = FREE;
        me->isHungry__[n] = 0;
    }
    return Q_TRAN(&Table::serving);
}
Note:
The QSpy log utility must capture the signal dictionary record in order to use the human-readable information. You need to connect to the target before the dictionary entries have been transmitted.

The following QSpy log example shows the signal dictionary records generated from the Table initial transition and subsequent records that show human-readable names of the signals:

qspy -fqs.bin -S2 -Q2 -P4 -p4 -T4    
QSpy 4.0.00
Thu Apr 06 09:56:10 2005
-f qs.bin
-S 2
-Q 2
-P 4
-p 4
-T 4
. . .      . . .
           Obj Dic: 00419048->table
           EQ.INIT: Obj=00419050 Len= 5
0000000000 AO.ADD : Active=table Prio=51
           Fun Dic: 00401CEE->Table_serving
           Sig Dic: 00000004,Obj=00419048 ->HUNGRY_SIG
           Sig Dic: 00000005,Obj=00419048 ->DONE_SIG
           Sig Dic: 00000006,Obj=00000000 ->EAT_SIG
0000000000 AO.SUB : Active=table Sig=HUNGRY_SIG
0000000000 AO.SUB : Active=table Sig=DONE_SIG
0000000000 AO.SUB : Active=table Sig=00000007,Obj=00419048
           Q_INIT : Obj=table Source=00403CE0 Target=Table_serving
0000000000 ==>Init: Obj=table New=Table_serving
. . .      . . .

// the Philosophers become hungry...


0000000007 AO.FIFO: Obj=table Evt(Sig=HUNGRY_SIG, Pool=1, Ref= 1)
           Queue(nUsed=  0, nMax=  0)
0000000007 AO.FIFO: Obj=table Evt(Sig=HUNGRY_SIG, Pool=1, Ref= 1)
           Queue(nUsed=  0, nMax=  0)
0000000007 AO.FIFO: Obj=table Evt(Sig=HUNGRY_SIG, Pool=1, Ref= 1)
           Queue(nUsed=  1, nMax=  1)
0000000007 AO.FIFO: Obj=table Evt(Sig=HUNGRY_SIG, Pool=1, Ref= 1)
           Queue(nUsed=  2, nMax=  2)
           Q_ENTRY: Obj=philo[2] State=Philosopher_hungry
0000000007 AO.GET : Active= table Evt(Sig=HUNGRY_SIG, Pool=1, Ref= 1)
           Queue(nUsed=  2)
0000000007 AO.FIFO: Obj=table Evt(Sig=HUNGRY_SIG, Pool=1, Ref= 1)
           Queue(nUsed=  2, nMax=  3)
           Q_ENTRY: Obj=philo[4] State=Philosopher_hungry
           Q_ENTRY: Obj=philo[1] State=Philosopher_hungry
           Q_ENTRY: Obj=philo[3] State=Philosopher_hungry
0000000007 ==>Tran: Obj=philo[2] Sig=TIMEOUT_SIG Source=Philosopher_thinking
           New=Philosopher_hungry
0000000007 ==>Tran: Obj=philo[4] Sig=TIMEOUT_SIG Source=Philosopher_thinking
           New=Philosopher_hungry
0000000007 ==>Tran: Obj=philo[3] Sig=TIMEOUT_SIG Source=Philosopher_thinking
           New=Philosopher_hungry
0000000007 ==>Tran: Obj=philo[1] Sig=TIMEOUT_SIG Source=Philosopher_thinking
           New=Philosopher_hungry
           Q_ENTRY: Obj=philo[0] State=Philosopher_hungry
0000000007 ==>Tran: Obj=philo[0] Sig=TIMEOUT_SIG Source=Philosopher_thinking
           New=Philosopher_hungry
           
// user record output           
0000000007 User070: 2 hungry

// Table grants permissions to eat   
0000000007 NEW    : Evt(Sig=EAT_SIG, size=    6)
0000000007 MP.GET : Obj=00418E18 nFree=   5 nMin=   5
0000000007 AO.FIFO: Obj=philo[4] Evt(Sig=EAT_SIG, Pool=1, Ref= 0)
           Queue(nUsed=  0, nMax=  0)
0000000007 AO.FIFO: Obj=philo[3] Evt(Sig=EAT_SIG, Pool=1, Ref= 0)
           Queue(nUsed=  0, nMax=  0)
0000000007 AO.FIFO: Obj=philo[2] Evt(Sig=EAT_SIG, Pool=1, Ref= 0)
           Queue(nUsed=  0, nMax=  0)
0000000007 AO.FIFO: Obj=philo[1] Evt(Sig=EAT_SIG, Pool=1, Ref= 0)
           Queue(nUsed=  0, nMax=  0)
0000000007 AO.FIFO: Obj=philo[0] Evt(Sig=EAT_SIG, Pool=1, Ref= 0)
           Queue(nUsed=  0, nMax=  0)
0000000007 PUBLISH: Evt(Sig=EAT_SIG, Pool=1, Ref= 5) nSubsr=  5
0000000007 AO.GETL: Active= philo[4] Evt(Sig=EAT_SIG, Pool=1, Ref= 5)
0000000007 AO.GETL: Active= philo[2] Evt(Sig=EAT_SIG, Pool=1, Ref= 5)
0000000007 AO.GETL: Active= philo[3] Evt(Sig=EAT_SIG, Pool=1, Ref= 5)
0000000007 AO.GETL: Active= philo[1] Evt(Sig=EAT_SIG, Pool=1, Ref= 5)
0000000007 AO.GETL: Active= philo[0] Evt(Sig=EAT_SIG, Pool=1, Ref= 5)
. . .      . . .

The following QSpy log example shows the same sequence of records, but with dictionary records removed. The human-readable signal names are not available.

qspy -fqs0.bin -S2 -Q2 -P4 -p4 -T4    
QSpy 4.0.00
Thu Apr 06 10:10:22 2005
-f qs0.bin
-S 2
-Q 2
-P 4
-p 4
-T 4
. . .      . . .
           Obj Dic: 00419048->table
           EQ.INIT: Obj=00419050 Len= 5
0000000000 AO.ADD : Active=table Prio=51

// the signal dictionary entries removed from the binary QS log
*** Dropped   4 records

0000000000 AO.SUB : Active=table Sig=00000004,Obj=00419048
0000000000 AO.SUB : Active=table Sig=00000005,Obj=00419048
0000000000 AO.SUB : Active=table Sig=00000007,Obj=00419048
           Q_INIT : Obj=table Source=00403CE0 Target=00403CE0
0000000000 ==>Init: Obj=table New=00401CEE
. . .      . . .

// the Philosophers become hungry...


0000000007 AO.FIFO: Obj=table Evt(Sig=00000004,Obj=00419048, Pool=1, Ref= 1)
           Queue(nUsed=  0, nMax=  0)
0000000007 AO.FIFO: Obj=table Evt(Sig=00000004,Obj=00419048, Pool=1, Ref= 1)
           Queue(nUsed=  0, nMax=  0)
0000000007 AO.FIFO: Obj=table Evt(Sig=00000004,Obj=00419048, Pool=1, Ref= 1)
           Queue(nUsed=  1, nMax=  1)
0000000007 AO.FIFO: Obj=table Evt(Sig=00000004,Obj=00419048, Pool=1, Ref= 1)
           Queue(nUsed=  2, nMax=  2)
           Q_ENTRY: Obj=philo[2] State=Philosopher_hungry
0000000007 AO.GET : Active= table Evt(Sig=00000004,Obj=00419048, Pool=1, Ref= 1)
           Queue(nUsed=  2)
0000000007 AO.FIFO: Obj=table Evt(Sig=00000004,Obj=00419048, Pool=1, Ref= 1)
           Queue(nUsed=  2, nMax=  3)
           Q_ENTRY: Obj=philo[4] State=Philosopher_hungry
           Q_ENTRY: Obj=philo[1] State=Philosopher_hungry
           Q_ENTRY: Obj=philo[3] State=Philosopher_hungry
0000000007 ==>Tran: Obj=philo[2] Sig=TIMEOUT_SIG Source=Philosopher_thinking
           New=Philosopher_hungry
0000000007 ==>Tran: Obj=philo[4] Sig=TIMEOUT_SIG Source=Philosopher_thinking
           New=Philosopher_hungry
0000000007 ==>Tran: Obj=philo[3] Sig=TIMEOUT_SIG Source=Philosopher_thinking
           New=Philosopher_hungry
0000000007 ==>Tran: Obj=philo[1] Sig=TIMEOUT_SIG Source=Philosopher_thinking
           New=Philosopher_hungry
           Q_ENTRY: Obj=philo[0] State=Philosopher_hungry
0000000007 ==>Tran: Obj=philo[0] Sig=TIMEOUT_SIG Source=Philosopher_thinking
           New=Philosopher_hungry
           
// user record output           
0000000007 User070: 2 hungry   

// Table grants permissions to eat   
0000000007 NEW    : Evt(Sig=00000006,Obj=00000000, size=    6)
0000000007 MP.GET : Obj=00418E18 nFree=   5 nMin=   5
0000000007 AO.FIFO: Obj=philo[4] Evt(Sig=00000006,Obj=00419000, Pool=1, Ref= 0) 
           Queue(nUsed=  0, nMax=  0)
0000000007 AO.FIFO: Obj=philo[3] Evt(Sig=00000006,Obj=00418FBC, Pool=1, Ref= 0)
           Queue(nUsed=  0, nMax=  0)
0000000007 AO.FIFO: Obj=philo[2] Evt(Sig=00000006,Obj=00418F78, Pool=1, Ref= 0)
           Queue(nUsed=  0, nMax=  0)
0000000007 AO.FIFO: Obj=philo[1] Evt(Sig=00000006,Obj=00418F34, Pool=1, Ref= 0)
           Queue(nUsed=  0, nMax=  0)
0000000007 AO.FIFO: Obj=philo[0] Evt(Sig=00000006,Obj=00418EF0, Pool=1, Ref= 0)
           Queue(nUsed=  0, nMax=  0)
0000000007 PUBLISH: Evt(Sig=00000006,Obj=00000000, Pool=1, Ref= 5) nSubsr=  5
0000000007 AO.GETL: Active= philo[4] Evt(Sig=00000006,Obj=00419000, Pool=1, Ref= 5)
0000000007 AO.GETL: Active= philo[2] Evt(Sig=00000006,Obj=00418F78, Pool=1, Ref= 5)
0000000007 AO.GETL: Active= philo[3] Evt(Sig=00000006,Obj=00418FBC, Pool=1, Ref= 5)
0000000007 AO.GETL: Active= philo[1] Evt(Sig=00000006,Obj=00418F34, Pool=1, Ref= 5)
0000000007 AO.GETL: Active= philo[0] Evt(Sig=00000006,Obj=00418EF0, Pool=1, Ref= 5)
. . .      . . .

Definition at line 986 of file qs.h.

#define QS_TIME_SIZE   4

The size (in bytes) of the QS time stamp. Valid values: 1, 2, or 4; default 4.

This macro can be defined in the QS port file (qs_port.h) to configure the QSTimeCtr type. Here the macro is not defined so the default of 4 byte is chosen.

Definition at line 66 of file qs.h.

#define QS_USR_DICTIONARY (   rec_)
Value:
do { \
    if (QS_GLB_FILTER_(QP_ QS_USR_DIC)) { \
        static char_t const Q_ROM Q_ROM_VAR usr_name_[] = #rec_; \
        QS_CRIT_STAT_ \
        QS_CRIT_ENTRY_(); \
        QP_ QS::begin(static_cast<uint8_t>(QP_ QS_USR_DIC)); \
        QS_U8_(static_cast<uint8_t>(rec_)); \
        QS_STR_ROM_(&usr_name_[0]); \
        QP_ QS::end(); \
        QS_CRIT_EXIT_(); \
        QP_ QS::onFlush(); \
    } \
} while (false)

Output user QS record dictionary record.

A user QS record dictionary record associates the numerical value of a user record with the human-readable identifier.

Definition at line 1056 of file qs.h.


Typedef Documentation

typedef uint32_t QSTimeCtr

The type of the QS time stamp.

This type determines the dynamic range of QS time stamps

Definition at line 183 of file qs.h.


Enumeration Type Documentation

Quantum Spy record types.

The following constants specify the QS record types used in QP components. You can specify your own record types starting from the QS_USER offset. Currently, the maximum of all records cannot exceed 256.

See also:
QS::filterOn()/QS_FILTER_ON and QS::filterOff()/QS_FILTER_OFF
Enumerator:
QS_QP_RESET 

reset the QP (start of a new QS session)

QS_QEP_STATE_ENTRY 

a state was entered

QS_QEP_STATE_EXIT 

a state was exited

QS_QEP_STATE_INIT 

an initial transition was taken in a state

QS_QEP_INIT_TRAN 

the top-most initial transition was taken

QS_QEP_INTERN_TRAN 

an internal transition was taken

QS_QEP_TRAN 

a regular transition was taken

QS_QEP_IGNORED 

an event was ignored (silently discarded)

QS_QEP_DISPATCH 

an event was dispatched (begin of RTC step)

QS_QEP_UNHANDLED 

an event was unhandled due to a guard

QS_QF_ACTIVE_ADD 

an AO has been added to QF (started)

QS_QF_ACTIVE_REMOVE 

an AO has been removed from QF (stopped)

QS_QF_ACTIVE_SUBSCRIBE 

an AO subscribed to an event

QS_QF_ACTIVE_UNSUBSCRIBE 

an AO unsubscribed to an event

QS_QF_ACTIVE_POST_FIFO 

an event was posted (FIFO) directly to an AO

QS_QF_ACTIVE_POST_LIFO 

an event was posted (LIFO) directly to an AO

QS_QF_ACTIVE_GET 

an AO got an event and its queue is still not empty

QS_QF_ACTIVE_GET_LAST 

an AO got an event and its queue is empty

QS_QF_EQUEUE_INIT 

an event queue was initialized

QS_QF_EQUEUE_POST_FIFO 

an event was posted (FIFO) to a raw queue

QS_QF_EQUEUE_POST_LIFO 

an event was posted (LIFO) to a raw queue

QS_QF_EQUEUE_GET 

get an event and queue still not empty

QS_QF_EQUEUE_GET_LAST 

get the last event from the queue

QS_QF_MPOOL_INIT 

a memory pool was initialized

QS_QF_MPOOL_GET 

a memory block was removed from a memory pool

QS_QF_MPOOL_PUT 

a memory block was returned to a memory pool

QS_QF_PUBLISH 

an event was truly published to some subscribers

QS_QF_NEW 

new event creation

QS_QF_GC_ATTEMPT 

garbage collection attempt

QS_QF_GC 

garbage collection

QS_QF_TICK 

QF::tick() was called.

QS_QF_TIMEEVT_ARM 

a time event was armed

QS_QF_TIMEEVT_AUTO_DISARM 

a time event expired and was disarmed

QS_QF_TIMEEVT_DISARM_ATTEMPT 

an attempt to disarm a disarmed QTimeEvt

QS_QF_TIMEEVT_DISARM 

true disarming of an armed time event

QS_QF_TIMEEVT_REARM 

rearming of a time event

QS_QF_TIMEEVT_POST 

a time event posted itself directly to an AO

QS_QF_TIMEEVT_CTR 

a time event counter was requested

QS_QF_CRIT_ENTRY 

critical section was entered

QS_QF_CRIT_EXIT 

critical section was exited

QS_QF_ISR_ENTRY 

an ISR was entered

QS_QF_ISR_EXIT 

an ISR was exited

QS_QF_INT_DISABLE 

interrupts were disabled

QS_QF_INT_ENABLE 

interrupts were enabled

QS_QK_MUTEX_LOCK 

the QK mutex was locked

QS_QK_MUTEX_UNLOCK 

the QK mutex was unlocked

QS_QK_SCHEDULE 

the QK scheduler scheduled a new task to execute

QS_SIG_DIC 

signal dictionary entry

QS_OBJ_DIC 

object dictionary entry

QS_FUN_DIC 

function dictionary entry

QS_USR_DIC 

user QS record dictionary entry

QS_ASSERT 

assertion fired in the code

QS_USER 

the first record available for user QS records

Definition at line 79 of file qs.h.

enum QSType

Enumerates data formats recognized by QS.

QS uses this enumeration is used only internally for the formatted user data elements.

Enumerator:
QS_I8_T 

signed 8-bit integer format

QS_U8_T 

unsigned 8-bit integer format

QS_I16_T 

signed 16-bit integer format

QS_U16_T 

unsigned 16-bit integer format

QS_I32_T 

signed 32-bit integer format

QS_U32_T 

unsigned 32-bit integer format

QS_F32_T 

32-bit floating point format

QS_F64_T 

64-bit floating point format

QS_STR_T 

zero-terminated ASCII string format

QS_MEM_T 

up to 255-bytes memory block format

QS_SIG_T 

event signal format

QS_OBJ_T 

object pointer format

QS_FUN_T 

function pointer format

QS_I64_T 

signed 64-bit integer format

QS_U64_T 

unsigned 64-bit integer format

QS_U32_HEX_T 

unsigned 32-bit integer in hex format

Definition at line 463 of file qs.h.


Variable Documentation

uint8_t QF_critNest_

critical section nesting level

Note:
Not to be used by Clients directly, only in ports of QF