QP/C++  6.9.3
Real-Time Embedded Framework
qs.hpp File Reference

QS/C++ platform-independent public interface. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  QSpyId
 QS ID type for applying local filtering. More...
 
class  QS
 
struct  QS::QSrxPriv
 
class  QActiveDummy
 

Namespaces

 QP
 

Macros

#define QS_TIME_PRE_()   (QP::QS::u8_raw_(QP::QS::onGetTime()))
 
#define QS_INIT(arg_)   (QP::QS::onStartup(arg_))
 
#define QS_EXIT()   (QP::QS::onCleanup())
 
#define QS_GLB_FILTER(rec_)    (QP::QS::glbFilter_(static_cast<std::int_fast16_t>(rec_)))
 
#define QS_LOC_FILTER(qs_id_)    (QP::QS::locFilter_(static_cast<std::int_fast16_t>(qs_id_)))
 
#define QS_BEGIN_ID(rec_, qs_id_)
 
#define QS_END()
 
#define QS_BEGIN_NOCRIT(rec_, qs_id_)
 Begin a QS user record without entering critical section. More...
 
#define QS_END_NOCRIT()
 End a QS user record without exiting critical section. More...
 
#define QS_REC_DONE()   (static_cast<void>(0))
 macro to hook up user code when a QS record is produced More...
 
#define QS_GLB_CHECK_(rec_)
 helper macro for checking the global QS filter More...
 
#define QS_LOC_CHECK_(qs_id_)
 helper macro for checking the local QS filter More...
 
#define QS_CRIT_STAT_
 
#define QS_CRIT_E_()   QF_CRIT_ENTRY(dummy)
 
#define QS_CRIT_X_()   QF_CRIT_EXIT(dummy); QS_REC_DONE()
 
#define QS_I8(width_, data_)
 Output formatted std::int8_t to the QS record. More...
 
#define QS_U8(width_, data_)
 Output formatted std::uint8_t to the QS record. More...
 
#define QS_I16(width_, data_)
 Output formatted std::int16_t to the QS record. More...
 
#define QS_U16(width_, data_)
 Output formatted std::uint16_t to the QS record. More...
 
#define QS_I32(width_, data_)
 Output formatted std::int32_t to the QS record. More...
 
#define QS_U32(width_, data_)
 Output formatted std::uint32_t to the QS record. More...
 
#define QS_I64(width_, data_)
 Output formatted std::int64_t to the QS record. More...
 
#define QS_U64(width_, data_)
 Output formatted std::uint64_t to the QS record. More...
 
#define QS_F32(width_, data_)
 Output formatted 32-bit floating point number to the QS record. More...
 
#define QS_F64(width_, data_)
 Output formatted 64-bit floating point number to the QS record. More...
 
#define QS_STR(str_)   (QP::QS::str_fmt_(str_))
 Output formatted zero-terminated ASCII string to the QS record. More...
 
#define QS_MEM(mem_, size_)   (QP::QS::mem_fmt_((mem_), (size_)))
 Output formatted memory block of up to 255 bytes to the QS record. More...
 
#define QS_OBJ(obj_)
 Output formatted object pointer to the QS record. More...
 
#define QS_FUN(fun_)
 Output formatted function pointer to the QS record. More...
 
#define QS_SIG(sig_, obj_)
 
#define QS_SIG_DICTIONARY(sig_, obj_)    (QP::QS::sig_dict_pre_((sig_), (obj_), #sig_))
 
#define QS_OBJ_DICTIONARY(obj_)    (QP::QS::obj_dict_pre_((obj_), #obj_))
 
#define QS_FUN_DICTIONARY(fun_)
 
#define QS_USR_DICTIONARY(rec_)
 
#define QS_ASSERTION(module_, loc_, delay_)    (QP::QS::assertion_pre_((module_), (loc_), (delay_)))
 Produce the assertion failure trace record. More...
 
#define QF_QS_CRIT_ENTRY()   (QP::QS::crit_entry_pre_())
 Output the critical section entry record. More...
 
#define QF_QS_CRIT_EXIT()   (QP::QS::crit_exit_pre_())
 Output the critical section exit record. More...
 
#define QF_QS_ISR_ENTRY(isrnest_, prio_)    (QP::QS::isr_entry_pre_((isrnest_), (prio_)))
 Output the interrupt entry record. More...
 
#define QF_QS_ISR_EXIT(isrnest_, prio_)    (QP::QS::isr_exit_pre_((isrnest_), (prio_)))
 Output the interrupt exit record. More...
 
#define QS_FLUSH()   (QP::QS::onFlush())
 
#define QF_QS_ACTION(act_)   (act_)
 Execute an action that is only necessary for QS output. More...
 
#define QS_OUTPUT()   (QS_output())
 
#define QS_RX_INPUT()   (QS_rx_input())
 
#define QS_TEST_PROBE_DEF(fun_)
 QS macro to define the Test-Probe for a given fun_. More...
 
#define QS_TEST_PROBE(code_)    if (qs_tp_ != 0U) { code_ }
 QS macro to apply a Test-Probe. More...
 
#define QS_TEST_PROBE_ID(id_, code_)    if (qs_tp_ == static_cast<std::uint32_t>(id_)) { code_ }
 QS macro to apply a Test-Probe. More...
 
#define QS_TEST_PAUSE()
 QS macro to pause test execution and enter the test event loop. More...
 

Typedefs

using QSTimeCtr = std::uint8_t
 
using QSCtr = std::uint_fast16_t
 QS ring buffer counter and offset type. More...
 

Enumerations

enum  QSpyRecords : std::int8_t {
  QS_EMPTY , 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_DEFER , QS_QF_ACTIVE_RECALL ,
  QS_QF_ACTIVE_SUBSCRIBE , QS_QF_ACTIVE_UNSUBSCRIBE , QS_QF_ACTIVE_POST , QS_QF_ACTIVE_POST_LIFO ,
  QS_QF_ACTIVE_GET , QS_QF_ACTIVE_GET_LAST , QS_QF_ACTIVE_RECALL_ATTEMPT , QS_QF_EQUEUE_POST ,
  QS_QF_EQUEUE_POST_LIFO , QS_QF_EQUEUE_GET , QS_QF_EQUEUE_GET_LAST , QS_QF_NEW_ATTEMPT ,
  QS_QF_MPOOL_GET , QS_QF_MPOOL_PUT , QS_QF_PUBLISH , QS_QF_NEW_REF ,
  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_DELETE_REF , 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_QF_ACTIVE_POST_ATTEMPT , QS_QF_EQUEUE_POST_ATTEMPT , QS_QF_MPOOL_GET_ATTEMPT ,
  QS_MUTEX_LOCK , QS_MUTEX_UNLOCK , QS_SCHED_LOCK , QS_SCHED_UNLOCK ,
  QS_SCHED_NEXT , QS_SCHED_IDLE , QS_SCHED_RESUME , QS_QEP_TRAN_HIST ,
  QS_QEP_TRAN_EP , QS_QEP_TRAN_XP , QS_TEST_PAUSED , QS_TEST_PROBE_GET ,
  QS_SIG_DICT , QS_OBJ_DICT , QS_FUN_DICT , QS_USR_DICT ,
  QS_TARGET_INFO , QS_TARGET_DONE , QS_RX_STATUS , QS_QUERY_DATA ,
  QS_PEEK_DATA , QS_ASSERT_FAIL , QS_QF_RUN , QS_RESERVED_71 ,
  QS_RESERVED_72 , QS_RESERVED_73 , QS_RESERVED_74 , QS_RESERVED_75 ,
  QS_RESERVED_76 , QS_RESERVED_77 , QS_RESERVED_78 , QS_RESERVED_79 ,
  QS_RESERVED_80 , QS_RESERVED_81 , QS_RESERVED_82 , QS_RESERVED_83 ,
  QS_RESERVED_84 , QS_RESERVED_85 , QS_RESERVED_86 , QS_RESERVED_87 ,
  QS_RESERVED_88 , QS_RESERVED_89 , QS_RESERVED_90 , QS_RESERVED_91 ,
  QS_RESERVED_92 , QS_RESERVED_93 , QS_RESERVED_94 , QS_RESERVED_95 ,
  QS_RESERVED_96 , QS_RESERVED_97 , QS_RESERVED_98 , QS_RESERVED_99 ,
  QS_USER
}
 
enum  QSpyRecordGroups : std::int16_t {
  QS_ALL_RECORDS = static_cast<std::uint8_t>(0xF0U) , QS_SM_RECORDS , QS_AO_RECORDS , QS_EQ_RECORDS ,
  QS_MP_RECORDS , QS_TE_RECORDS , QS_QF_RECORDS , QS_SC_RECORDS ,
  QS_U0_RECORDS , QS_U1_RECORDS , QS_U2_RECORDS , QS_U3_RECORDS ,
  QS_U4_RECORDS , QS_UA_RECORDS
}
 QS record groups for QS_GLB_FILTER() More...
 
enum  QSpyUserOffsets : std::int16_t {
  QS_USER0 = QS_USER , QS_USER1 = QS_USER0 + 5 , QS_USER2 = QS_USER1 + 5 , QS_USER3 = QS_USER2 + 5 ,
  QS_USER4 = QS_USER3 + 5
}
 QS user record group offsets for QS_GLB_FILTER() More...
 
enum  QSpyIdOffsets : std::int16_t { QS_AO_ID = 0 , QS_EP_ID = 64 , QS_EQ_ID = 80 , QS_AP_ID = 96 }
 QS ID offsets for QS_LOC_FILTER() More...
 
enum  QSpyIdGroups : std::int16_t {
  QS_ALL_IDS = 0xF0 , QS_AO_IDS = 0x80 + QS_AO_ID , QS_EP_IDS = 0x80 + QS_EP_ID , QS_EQ_IDS = 0x80 + QS_EQ_ID ,
  QS_AP_IDS = 0x80 + QS_AP_ID
}
 QS ID groups for QS_LOC_FILTER() More...
 
enum  QSpyRxRecords : std::uint8_t {
  QS_RX_INFO , QS_RX_COMMAND , QS_RX_RESET , QS_RX_TICK ,
  QS_RX_PEEK , QS_RX_POKE , QS_RX_FILL , QS_RX_TEST_SETUP ,
  QS_RX_TEST_TEARDOWN , QS_RX_TEST_PROBE , QS_RX_GLB_FILTER , QS_RX_LOC_FILTER ,
  QS_RX_AO_FILTER , QS_RX_CURR_OBJ , QS_RX_TEST_CONTINUE , QS_RX_QUERY_CURR ,
  QS_RX_EVENT
}
 

Variables

constexpr std::uint16_t QS_EOD = 0xFFFFU
 
constexpr std::uint8_t QUTEST_ON_POST {124U}
 
std::uint8_t volatile QF_intNest
 

Detailed Description

QS/C++ platform-independent public interface.

Definition in file qs.hpp.


Data Structure Documentation

◆ QP::QS::QSrxPriv

struct QP::QS::QSrxPriv

Definition at line 556 of file qs.hpp.

Collaboration diagram for QS::QSrxPriv:
Collaboration graph
Data Fields
void * currObj[MAX_OBJ] current objects
uint8_t * buf pointer to the start of the ring buffer
QSCtr end offset of the end of the ring buffer
QSCtr head offset to where next byte will be inserted
QSCtr tail offset of where next byte will be extracted
QPSet readySet QUTEST ready-set of active objects.
bool inTestLoop QUTest event loop is running.

Macro Definition Documentation

◆ QS_TIME_PRE_

#define QS_TIME_PRE_ ( )    (QP::QS::u8_raw_(QP::QS::onGetTime()))

Definition at line 266 of file qs.hpp.

◆ QS_INIT

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

Initialize the QS facility.

Description
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
QP::QS::onStartup(), example of setting up a QS filter in QS_GLB_FILTER()

Definition at line 668 of file qs.hpp.

◆ QS_EXIT

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

Cleanup the QS facility.

Description
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
QP::QS::onCleanup()

Definition at line 675 of file qs.hpp.

◆ QS_GLB_FILTER

#define QS_GLB_FILTER (   rec_)     (QP::QS::glbFilter_(static_cast<std::int_fast16_t>(rec_)))

Global Filter ON for a given record type rec.

Description
This macro provides an indirection layer to call QP::QS::filterOn() if Q_SPY is defined, or do nothing if Q_SPY is not defined.
Usage
The following example shows how to use QS filters:
int main(int arc, char *argv[]) {
. . .
if (!QS_INIT(argv)) { // Initialize QS target component
return -1; // Unable to initialize QSpy
}
// apply the global QS filters...
// NOTE: global filters start as being all OFF
QS_GLB_FILTER(QS_QF_RECORDS); // turn QF-group ON
QS_GLB_FILTER(-QS_QF_TICK); // turn #QS_QF_TICK OFF
// apply the local QS filters...
// NOTE: local filters start as being all ON
QS_LOC_FILTER(-QS_EP_IDS); // turn EP (Event-Pool) group OFF
QS_LOC_FILTER(3); // turn AO with prioity 3 ON
// start the active objects...
. . .
// NOTE: the following will work only after AO_Table has been started
QS_LOC_FILTER(-AO_Table->prio); // turn AO_Table OFF
. . .
}
@ QS_QF_TICK
QP::QF::tickX() was called.
Definition: qs.hpp:107
@ QS_EP_IDS
event-pool IDs
Definition: qs.hpp:238
@ QS_QF_RECORDS
QF QS records.
Definition: qs.hpp:207
#define QS_LOC_FILTER(qs_id_)
Definition: qs.hpp:695
#define QS_GLB_FILTER(rec_)
Definition: qs.hpp:685
#define QS_INIT(arg_)
Definition: qs.hpp:668

Definition at line 685 of file qs.hpp.

◆ QS_LOC_FILTER

#define QS_LOC_FILTER (   qs_id_)     (QP::QS::locFilter_(static_cast<std::int_fast16_t>(qs_id_)))

Local Filter for a given state machine object qs_id.

Description
This macro provides an indirection layer to call QS_locFilter_() if Q_SPY is defined, or do nothing if Q_SPY is not defined.

The following example shows how to use QS filters:

int main(int arc, char *argv[]) {
. . .
if (!QS_INIT(argv)) { // Initialize QS target component
return -1; // Unable to initialize QSpy
}
// apply the global QS filters...
// NOTE: global filters start as being all OFF
QS_GLB_FILTER(QS_QF_RECORDS); // turn QF-group ON
QS_GLB_FILTER(-QS_QF_TICK); // turn #QS_QF_TICK OFF
// apply the local QS filters...
// NOTE: local filters start as being all ON
QS_LOC_FILTER(-QS_EP_IDS); // turn EP (Event-Pool) group OFF
QS_LOC_FILTER(3); // turn AO with prioity 3 ON
// start the active objects...
. . .
// NOTE: the following will work only after AO_Table has been started
QS_LOC_FILTER(-AO_Table->prio); // turn AO_Table OFF
. . .
}

Definition at line 695 of file qs.hpp.

◆ QS_BEGIN_ID

#define QS_BEGIN_ID (   rec_,
  qs_id_ 
)
Value:
if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \
QP::QS::beginRec_(static_cast<std::uint_fast8_t>(rec_)); \
QS_TIME_PRE_();
unsigned int uint_fast8_t
Definition: 16bit/stdint.h:36
static void beginRec_(std::uint_fast8_t const rec) noexcept
Mark the begin of a QS record rec.
Definition: qs.cpp:410
#define QS_CRIT_E_()
Definition: qs.hpp:793
#define QS_LOC_CHECK_(qs_id_)
helper macro for checking the local QS filter
Definition: qs.hpp:750
#define QS_GLB_CHECK_(rec_)
helper macro for checking the global QS filter
Definition: qs.hpp:744

Begin a user QS record with entering critical section.

Description
The following example shows how to build a user QS record using the macros QS_BEGIN_ID(), QS_END(), and the formatted output macros: QS_U8(), QS_STR(), etc.
Note
Must always be used in pair with QS_END()
#ifdef Q_SPY
enum {
PHILO_STAT = QP::QS_USER
};
. . .
#endif
void BSP_displayPhilStat(uint8_t n, char const *stat) {
. . .
// application-specific record
QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->m_prio)
QS_U8(1, n); // Philosopher number
QS_STR(stat); // Philosopher status
}
unsigned char uint8_t
Definition: 16bit/stdint.h:29
@ QS_USER
the first record available to QS users
Definition: qs.hpp:196
#define QS_U8(width_, data_)
Output formatted std::uint8_t to the QS record.
Definition: qs.hpp:824
#define QS_END()
Definition: qs.hpp:722
#define QS_BEGIN_ID(rec_, qs_id_)
Definition: qs.hpp:712
#define QS_STR(str_)
Output formatted zero-terminated ASCII string to the QS record.
Definition: qs.hpp:877

Definition at line 712 of file qs.hpp.

◆ QS_END

#define QS_END ( )
Value:
QS_CRIT_X_(); \
}
static void endRec_(void) noexcept
Mark the end of a QS record rec.
Definition: qs.cpp:436

End a QS record with exiting critical section.

See also
example for QS_BEGIN_ID()
Note
Must always be used in pair with QS_BEGIN_ID()

Definition at line 722 of file qs.hpp.

◆ QS_BEGIN_NOCRIT

#define QS_BEGIN_NOCRIT (   rec_,
  qs_id_ 
)
Value:
if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \
QS_TIME_PRE_();

Begin a QS user record without entering critical section.

Definition at line 728 of file qs.hpp.

◆ QS_END_NOCRIT

#define QS_END_NOCRIT ( )
Value:

End a QS user record without exiting critical section.

Definition at line 734 of file qs.hpp.

◆ QS_REC_DONE

#define QS_REC_DONE ( )    (static_cast<void>(0))

macro to hook up user code when a QS record is produced

Definition at line 740 of file qs.hpp.

◆ QS_GLB_CHECK_

#define QS_GLB_CHECK_ (   rec_)
Value:
((QP::QS::priv_.glbFilter[static_cast<std::uint_fast8_t>(rec_) >> 3] \
& static_cast<std::uint8_t>(1U \
<< (static_cast<std::uint_fast8_t>(rec_) & 7U))) != 0U)
static QS priv_
Definition: qs.hpp:554
std::uint8_t glbFilter[16]
global on/off QS filter
Definition: qs.hpp:540

helper macro for checking the global QS filter

Definition at line 744 of file qs.hpp.

◆ QS_LOC_CHECK_

#define QS_LOC_CHECK_ (   qs_id_)
Value:
((QP::QS::priv_.locFilter[static_cast<std::uint_fast8_t>(qs_id_) >> 3] \
& static_cast<std::uint8_t>(1U \
<< (static_cast<std::uint_fast8_t>(qs_id_) & 7U))) != 0U)
std::uint8_t locFilter[16]
lobal on/off QS filter
Definition: qs.hpp:541

helper macro for checking the local QS filter

Definition at line 750 of file qs.hpp.

◆ QS_CRIT_STAT_

#define QS_CRIT_STAT_

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

Description
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 783 of file qs.hpp.

◆ QS_CRIT_E_

#define QS_CRIT_E_ ( )    QF_CRIT_ENTRY(dummy)

This is an internal macro for entering a critical section.

Description
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 793 of file qs.hpp.

◆ QS_CRIT_X_

#define QS_CRIT_X_ ( )    QF_CRIT_EXIT(dummy); QS_REC_DONE()

This is an internal macro for exiting a critical section.

Description
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 803 of file qs.hpp.

◆ QS_I8

#define QS_I8 (   width_,
  data_ 
)
Value:
(QP::QS::u8_fmt_(static_cast<std::uint8_t>( \
(static_cast<std::uint8_t>(width_) << 4)) \
| static_cast<std::uint8_t>(QP::QS::I8_T)), (data_)))
static void u8_fmt_(std::uint8_t const format, std::uint8_t const d) noexcept
Output std::uint8_t data element with format information.
Definition: qs.cpp:579
@ I8_T
signed 8-bit integer format
Definition: qs.hpp:495

Output formatted std::int8_t to the QS record.

Definition at line 818 of file qs.hpp.

◆ QS_U8

#define QS_U8 (   width_,
  data_ 
)
Value:
(QP::QS::u8_fmt_(static_cast<std::uint8_t>( \
(static_cast<std::uint8_t>((width_) << 4)) \
| static_cast<std::uint8_t>(QP::QS::U8_T)), (data_)))
@ U8_T
unsigned 8-bit integer format
Definition: qs.hpp:496

Output formatted std::uint8_t to the QS record.

Definition at line 824 of file qs.hpp.

◆ QS_I16

#define QS_I16 (   width_,
  data_ 
)
Value:
(QP::QS::u16_fmt_(static_cast<std::uint8_t>( \
(static_cast<std::uint8_t>((width_) << 4)) \
| static_cast<std::uint8_t>(QP::QS::I16_T)), (data_)))
@ I16_T
signed 16-bit integer format
Definition: qs.hpp:497
static void u16_fmt_(std::uint8_t format, std::uint16_t d) noexcept
output std::uint16_t data element with format information
Definition: qs.cpp:599

Output formatted std::int16_t to the QS record.

Definition at line 830 of file qs.hpp.

◆ QS_U16

#define QS_U16 (   width_,
  data_ 
)
Value:
(QP::QS::u16_fmt_(static_cast<std::uint8_t>((((width_) << 4)) \
| static_cast<std::uint8_t>(QP::QS::U16_T)), (data_)))
@ U16_T
unsigned 16-bit integer format
Definition: qs.hpp:498

Output formatted std::uint16_t to the QS record.

Definition at line 836 of file qs.hpp.

◆ QS_I32

#define QS_I32 (   width_,
  data_ 
)
Value:
static_cast<std::uint8_t>((static_cast<std::uint8_t>((width_) << 4)) \
| static_cast<std::uint8_t>(QP::QS::I32_T)), (data_)))
static void u32_fmt_(std::uint8_t format, std::uint32_t d) noexcept
Output std::uint32_t data element with format information.
Definition: qs.cpp:624
@ I32_T
signed 32-bit integer format
Definition: qs.hpp:499

Output formatted std::int32_t to the QS record.

Definition at line 841 of file qs.hpp.

◆ QS_U32

#define QS_U32 (   width_,
  data_ 
)
Value:
(QP::QS::u32_fmt_(static_cast<std::uint8_t>( \
(static_cast<std::uint8_t>((width_) << 4)) \
| static_cast<std::uint8_t>(QP::QS::U32_T)), (data_)))
@ U32_T
unsigned 32-bit integer format
Definition: qs.hpp:500

Output formatted std::uint32_t to the QS record.

Definition at line 847 of file qs.hpp.

◆ QS_I64

#define QS_I64 (   width_,
  data_ 
)
Value:
(QP::QS::u64_fmt_(static_cast<std::uint8_t>( \
(static_cast<std::uint8_t>((width_) << 4)) \
| static_cast<std::uint8_t>(QP::QS::I64_T)), (data_)))
static void u64_fmt_(std::uint8_t format, std::uint64_t d) noexcept
Output uint64_t data element with format information.
Definition: qs_64bit.cpp:70
@ I64_T
signed 64-bit integer format
Definition: qs.hpp:508

Output formatted std::int64_t to the QS record.

Definition at line 853 of file qs.hpp.

◆ QS_U64

#define QS_U64 (   width_,
  data_ 
)
Value:
(QP::QS::u64_fmt_(static_cast<std::uint8_t>( \
(static_cast<std::uint8_t>((width_) << 4)) \
| static_cast<std::uint8_t>(QP::QS::U64_T)), (data_)))
@ U64_T
unsigned 64-bit integer format
Definition: qs.hpp:509

Output formatted std::uint64_t to the QS record.

Definition at line 859 of file qs.hpp.

◆ QS_F32

#define QS_F32 (   width_,
  data_ 
)
Value:
(QP::QS::f32_fmt_(static_cast<std::uint8_t>( \
(static_cast<std::uint8_t>((width_) << 4)) \
| static_cast<std::uint8_t>(QP::QS::F32_T)), (data_)))
static void f32_fmt_(std::uint8_t format, float32_t const d) noexcept
Output 32-bit floating point data element with format information.
Definition: qs_fp.cpp:49
@ F32_T
32-bit floating point format
Definition: qs.hpp:501

Output formatted 32-bit floating point number to the QS record.

Definition at line 865 of file qs.hpp.

◆ QS_F64

#define QS_F64 (   width_,
  data_ 
)
Value:
(QP::QS::f64_fmt_(static_cast<std::uint8_t>( \
(static_cast<std::uint8_t>((width_) << 4)) \
| static_cast<std::uint8_t>(QP::QS::F64_T)), (data_)))
static void f64_fmt_(std::uint8_t format, float64_t const d) noexcept
Output 64-bit floating point data element with format information.
Definition: qs_fp.cpp:78
@ F64_T
64-bit floating point format
Definition: qs.hpp:502

Output formatted 64-bit floating point number to the QS record.

Definition at line 871 of file qs.hpp.

◆ QS_STR

#define QS_STR (   str_)    (QP::QS::str_fmt_(str_))

Output formatted zero-terminated ASCII string to the QS record.

Definition at line 877 of file qs.hpp.

◆ QS_MEM

#define QS_MEM (   mem_,
  size_ 
)    (QP::QS::mem_fmt_((mem_), (size_)))

Output formatted memory block of up to 255 bytes to the QS record.

Definition at line 880 of file qs.hpp.

◆ QS_OBJ

#define QS_OBJ (   obj_)
Value:
reinterpret_cast<std::uint32_t>(obj_)))
unsigned long int uint32_t
Definition: 16bit/stdint.h:31
@ OBJ_T
object pointer format
Definition: qs.hpp:506

Output formatted object pointer to the QS record.

Definition at line 897 of file qs.hpp.

◆ QS_FUN

#define QS_FUN (   fun_)
Value:
reinterpret_cast<std::uint32_t>(fun_)))
@ FUN_T
function pointer format
Definition: qs.hpp:507

Output formatted function pointer to the QS record.

Definition at line 916 of file qs.hpp.

◆ QS_SIG

#define QS_SIG (   sig_,
  obj_ 
)
Value:
unsigned int uint16_t
Definition: 16bit/stdint.h:30
static void obj_raw_(void const *const obj) noexcept
Output obj pointer data element without format information.
Definition: qs.cpp:801
@ SIG_T
event signal format
Definition: qs.hpp:505

Output formatted event signal (of type QP::QSignal) and the state machine object to the user QS record

Definition at line 936 of file qs.hpp.

◆ QS_SIG_DICTIONARY

#define QS_SIG_DICTIONARY (   sig_,
  obj_ 
)     (QP::QS::sig_dict_pre_((sig_), (obj_), #sig_))

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):

static Table l_table;
QP::QState Table::initial(Table * const me, QP::QEvt const * const e) {
(void)e; // suppress the compiler warning about unused parameter
QS_OBJ_DICTIONARY(&l_table);
QS_FUN_DICTIONARY(&Table::initial);
QS_FUN_DICTIONARY(&Table::active);
QS_FUN_DICTIONARY(&Table::serving);
QS_FUN_DICTIONARY(&Table::paused);
QS_SIG_DICTIONARY(DONE_SIG, (void *)0); // global signals
QS_SIG_DICTIONARY(EAT_SIG, (void *)0);
QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0);
QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0);
QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal just for Table
. . .
}
static QState top(void *const me, QEvt const *const e) noexcept
the top-state.
Definition: qep_hsm.cpp:224
std::uint_fast8_t QState
Type returned from state-handler functions.
Definition: qep.hpp:223
#define QS_OBJ_DICTIONARY(obj_)
Definition: qs.hpp:998
#define QS_FUN_DICTIONARY(fun_)
Definition: qs.hpp:1012
#define QS_SIG_DICTIONARY(sig_, obj_)
Definition: qs.hpp:983
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)
. . . . . .
#define PUBLISH(e_, sender_)
Definition: qf.hpp:839

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 983 of file qs.hpp.

◆ QS_OBJ_DICTIONARY

#define QS_OBJ_DICTIONARY (   obj_)     (QP::QS::obj_dict_pre_((obj_), #obj_))

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:

static Table l_table;
QP::QState Table::initial(Table * const me, QP::QEvt const * const e) {
(void)e; // suppress the compiler warning about unused parameter
QS_OBJ_DICTIONARY(&l_table);
QS_FUN_DICTIONARY(&Table::initial);
QS_FUN_DICTIONARY(&Table::active);
QS_FUN_DICTIONARY(&Table::serving);
QS_FUN_DICTIONARY(&Table::paused);
QS_SIG_DICTIONARY(DONE_SIG, (void *)0); // global signals
QS_SIG_DICTIONARY(EAT_SIG, (void *)0);
QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0);
QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0);
QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal just for Table
. . .
}

Definition at line 998 of file qs.hpp.

◆ QS_FUN_DICTIONARY

#define QS_FUN_DICTIONARY (   fun_)
Value:
QP::QS::force_cast<void (*)(void)>(fun_), #fun_))
static T_OUT force_cast(T_IN in)
Definition: qs.hpp:531
static void fun_dict_pre_(void(*const fun)(void), char_t const *name) noexcept
Output function dictionary record.
Definition: qs.cpp:974

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 1012 of file qs.hpp.

◆ QS_USR_DICTIONARY

#define QS_USR_DICTIONARY (   rec_)
Value:
do { \
static char_t const usr_name_[] = #rec_; \
QP::QS::usr_dict_pre_((rec_), &usr_name_[0]); \
} while (false)
static void usr_dict_pre_(enum_t const rec, char_t const *const name) noexcept
Output user dictionary record.
Definition: qs.cpp:646
char char_t
Definition: qassert.h:77

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 1020 of file qs.hpp.

◆ QS_ASSERTION

#define QS_ASSERTION (   module_,
  loc_,
  delay_ 
)     (QP::QS::assertion_pre_((module_), (loc_), (delay_)))

Produce the assertion failure trace record.

Definition at line 1026 of file qs.hpp.

◆ QF_QS_CRIT_ENTRY

#define QF_QS_CRIT_ENTRY ( )    (QP::QS::crit_entry_pre_())

Output the critical section entry record.

Definition at line 1030 of file qs.hpp.

◆ QF_QS_CRIT_EXIT

#define QF_QS_CRIT_EXIT ( )    (QP::QS::crit_exit_pre_())

Output the critical section exit record.

Definition at line 1033 of file qs.hpp.

◆ QF_QS_ISR_ENTRY

#define QF_QS_ISR_ENTRY (   isrnest_,
  prio_ 
)     (QP::QS::isr_entry_pre_((isrnest_), (prio_)))

Output the interrupt entry record.

Definition at line 1036 of file qs.hpp.

◆ QF_QS_ISR_EXIT

#define QF_QS_ISR_EXIT (   isrnest_,
  prio_ 
)     (QP::QS::isr_exit_pre_((isrnest_), (prio_)))

Output the interrupt exit record.

Definition at line 1040 of file qs.hpp.

◆ QS_FLUSH

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

Flush the QS trace data to the host

This macro invokes the QP::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 1049 of file qs.hpp.

◆ QF_QS_ACTION

#define QF_QS_ACTION (   act_)    (act_)

Execute an action that is only necessary for QS output.

Definition at line 1052 of file qs.hpp.

◆ QS_OUTPUT

#define QS_OUTPUT ( )    (QS_output())

macro to handle the QS output from the application NOTE: if this macro is used, the application must define QS_output().

Definition at line 1056 of file qs.hpp.

◆ QS_RX_INPUT

#define QS_RX_INPUT ( )    (QS_rx_input())

macro to handle the QS-RX input to the application NOTE: if this macro is used, the application must define QS_rx_input().

Definition at line 1060 of file qs.hpp.

◆ QS_TEST_PROBE_DEF

#define QS_TEST_PROBE_DEF (   fun_)
Value:
std::uint32_t const qs_tp_ = \
static std::uint32_t getTestProbe_(void(*const api)(void)) noexcept
internal function to get the Test-Probe for a given API
Definition: qs_rx.cpp:1318

QS macro to define the Test-Probe for a given fun_.

Definition at line 1068 of file qs.hpp.

◆ QS_TEST_PROBE

#define QS_TEST_PROBE (   code_)     if (qs_tp_ != 0U) { code_ }

QS macro to apply a Test-Probe.

Definition at line 1073 of file qs.hpp.

◆ QS_TEST_PROBE_ID

#define QS_TEST_PROBE_ID (   id_,
  code_ 
)     if (qs_tp_ == static_cast<std::uint32_t>(id_)) { code_ }

QS macro to apply a Test-Probe.

Definition at line 1077 of file qs.hpp.

◆ QS_TEST_PAUSE

#define QS_TEST_PAUSE ( )
Value:
do { \
} while (false)
static void onTestLoop(void)
callback to run the test loop
@ QS_TEST_PAUSED
test has been paused
Definition: qs.hpp:150

QS macro to pause test execution and enter the test event loop.

Definition at line 1081 of file qs.hpp.