QS/C platform-independent public interface. More...
Go to the source code of this file.
Classes | |
struct | QSpyId |
QS ID type for applying local filtering. More... | |
struct | QS_tx |
class | QS_rx |
QS software tracing parameters for QS input (QS-RX) More... | |
struct | QS_TProbe |
Test Probe attributes. More... | |
struct | QS_TestData |
QUTest data. More... | |
class | QHsmDummy |
QHsmDummy class. More... | |
class | QActiveDummy |
QActiveDummy Object class. More... | |
Macros | |
#define | QS_CTR_SIZE 2U |
#define | QS_TIME_SIZE 4U |
#define | QS_INIT(arg_) (QS_onStartup(arg_)) |
#define | QS_EXIT() (QS_onCleanup()) |
#define | QS_OUTPUT() (QS_output()) |
#define | QS_RX_INPUT() (QS_rx_input()) |
#define | QS_GLB_FILTER(rec_) (QS_glbFilter_((int_fast16_t)(rec_))) |
#define | QS_LOC_FILTER(qs_id_) (QS_locFilter_((int_fast16_t)(qs_id_))) |
#define | QS_BEGIN_ID(rec_, qs_id_) |
#define | QS_END() |
#define | QS_FLUSH() (QS_onFlush()) |
#define | QS_BEGIN_NOCRIT(rec_, qs_id_) |
#define | QS_END_NOCRIT() |
#define | QS_GLB_CHECK_(rec_) |
#define | QS_LOC_CHECK_(qs_id_) |
#define | QS_REC_DONE() ((void)0) |
#define | QS_I8(width_, data_) |
#define | QS_U8(width_, data_) (QS_u8_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U8_T, (data_))) |
#define | QS_I16(width_, data_) (QS_u16_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I16_T, (data_))) |
#define | QS_U16(width_, data_) (QS_u16_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U16_T, (data_))) |
#define | QS_I32(width_, data_) (QS_u32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I32_T, (data_))) |
#define | QS_U32(width_, data_) (QS_u32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U32_T, (data_))) |
#define | QS_I64(width_, data_) (QS_u64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I64_T, (data_))) |
#define | QS_U64(width_, data_) (QS_u64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U64_T, (data_))) |
#define | QS_F32(width_, data_) (QS_f32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_F32_T, (data_))) |
#define | QS_F64(width_, data_) (QS_f64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_F64_T, (data_))) |
#define | QS_STR(str_) (QS_str_fmt_((str_))) |
#define | QS_MEM(mem_, size_) (QS_mem_fmt_((mem_), (size_))) |
#define | QS_ENUM(group_, value_) |
#define | QS_TIME_PRE_() (QS_u32_raw_(QS_onGetTime())) |
#define | QS_OBJ(obj_) (QS_u32_fmt_(QS_OBJ_T, (uint32_t)(obj_))) |
#define | QS_FUN(fun_) (QS_u32_fmt_(QS_FUN_T, (uint32_t)(fun_))) |
#define | QS_SIG(sig_, obj_) |
#define | QS_SIG_DICTIONARY(sig_, obj_) (QS_sig_dict_pre_((sig_), (obj_), #sig_)) |
#define | QS_OBJ_DICTIONARY(obj_) (QS_obj_dict_pre_((obj_), #obj_)) |
#define | QS_OBJ_ARR_DICTIONARY(obj_, idx_) (QS_obj_arr_dict_pre_((obj_), (idx_), #obj_)) |
#define | QS_FUN_DICTIONARY(fun_) (QS_fun_dict_pre_((void (*)(void))(fun_), #fun_)) |
#define | QS_USR_DICTIONARY(rec_) (QS_usr_dict_pre_((rec_), #rec_)) |
#define | QS_ENUM_DICTIONARY(value_, group_) (QS_enum_dict_pre_((value_), (group_), #value_)) |
#define | QF_QS_ACTION(act_) (act_) |
#define | QS_EOD ((uint16_t)0xFFFFU) |
#define | QS_CMD ((uint8_t)7U) |
#define | QS_HEX_FMT ((uint8_t)0x0FU) |
#define | QS_CRIT_STAT_ |
#define | QS_CRIT_E_() QF_CRIT_ENTRY(dummy) |
#define | QS_CRIT_X_() QF_CRIT_EXIT(dummy); QS_REC_DONE() |
#define | QUTEST_ON_POST 124 |
#define | QS_TEST_PROBE_DEF(fun_) uint32_t const qs_tp_ = QS_getTestProbe_((void (*)(void))(fun_)); |
#define | QS_TEST_PROBE(code_) if (qs_tp_ != 0U) { code_ } |
#define | QS_TEST_PROBE_ID(id_, code_) if (qs_tp_ == (uint32_t)(id_)) { code_ } |
#define | QS_TEST_PAUSE() (QS_test_pause_()) |
Typedefs | |
typedef uint_fast16_t | QSCtr |
typedef uint32_t | QSTimeCtr |
typedef uint32_t | QSFun |
Enumerations | |
enum | QS_preType { QS_I8_ENUM_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 } |
Functions | |
void | QF_QS_CRIT_ENTRY (void) |
void | QF_QS_CRIT_EXIT (void) |
void | QF_QS_ISR_ENTRY (uint_fast8_t const isrnest, uint_fast8_t const prio_) |
void | QF_QS_ISR_EXIT (uint_fast8_t isrnest, uint_fast8_t prio) |
void | QS_test_pause_ (void) |
uint32_t | QS_getTestProbe_ (QSpyFunPtr const api) |
void | QS_onTestSetup (void) |
void | QS_onTestTeardown (void) |
void | QS_onTestEvt (QEvt *e) |
void | QS_onTestPost (void const *sender, QActive *recipient, QEvt const *e, bool status) |
void | QS_onTestLoop (void) |
void | QS_processTestEvts_ (void) |
Variables | |
QS_tx | QS_priv_ |
struct QS_TestData | QS_testData |
struct QS_TProbe |
struct QS_TestData |
#define QS_CTR_SIZE 2U |
#define QS_TIME_SIZE 4U |
#define QS_INIT | ( | arg_ | ) | (QS_onStartup(arg_)) |
#define QS_EXIT | ( | ) | (QS_onCleanup()) |
#define QS_OUTPUT | ( | ) | (QS_output()) |
#define QS_RX_INPUT | ( | ) | (QS_rx_input()) |
#define QS_GLB_FILTER | ( | rec_ | ) | (QS_glbFilter_((int_fast16_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.
#define QS_LOC_FILTER | ( | qs_id_ | ) | (QS_locFilter_((int_fast16_t)(qs_id_))) |
Local Filter for a given state machine object qs_id
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:
#define QS_BEGIN_ID | ( | rec_, | |
qs_id_ | |||
) |
Begin an application-specific QS record with entering critical section
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.
#define QS_END | ( | ) |
End an application-specific QS record with exiting critical section.
#define QS_FLUSH | ( | ) | (QS_onFlush()) |
#define QS_BEGIN_NOCRIT | ( | rec_, | |
qs_id_ | |||
) |
Begin an application-specific QS record WITHOUT entering critical section
#define QS_END_NOCRIT | ( | ) |
#define QS_GLB_CHECK_ | ( | rec_ | ) |
Helper macro for checking the global QS filter
#define QS_LOC_CHECK_ | ( | qs_id_ | ) |
Helper macro for checking the local QS filter
#define QS_REC_DONE | ( | ) | ((void)0) |
#define QS_I8 | ( | width_, | |
data_ | |||
) |
Output formatted int8_t to the QS record
#define QS_U8 | ( | width_, | |
data_ | |||
) | (QS_u8_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U8_T, (data_))) |
#define QS_I16 | ( | width_, | |
data_ | |||
) | (QS_u16_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I16_T, (data_))) |
#define QS_U16 | ( | width_, | |
data_ | |||
) | (QS_u16_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U16_T, (data_))) |
#define QS_I32 | ( | width_, | |
data_ | |||
) | (QS_u32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I32_T, (data_))) |
#define QS_U32 | ( | width_, | |
data_ | |||
) | (QS_u32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U32_T, (data_))) |
#define QS_I64 | ( | width_, | |
data_ | |||
) | (QS_u64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I64_T, (data_))) |
#define QS_U64 | ( | width_, | |
data_ | |||
) | (QS_u64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U64_T, (data_))) |
#define QS_F32 | ( | width_, | |
data_ | |||
) | (QS_f32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_F32_T, (data_))) |
#define QS_F64 | ( | width_, | |
data_ | |||
) | (QS_f64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_F64_T, (data_))) |
#define QS_STR | ( | str_ | ) | (QS_str_fmt_((str_))) |
#define QS_MEM | ( | mem_, | |
size_ | |||
) | (QS_mem_fmt_((mem_), (size_))) |
#define QS_ENUM | ( | group_, | |
value_ | |||
) |
Output formatted enumeration to the QS record
#define QS_TIME_PRE_ | ( | ) | (QS_u32_raw_(QS_onGetTime())) |
#define QS_OBJ | ( | obj_ | ) | (QS_u32_fmt_(QS_OBJ_T, (uint32_t)(obj_))) |
#define QS_FUN | ( | fun_ | ) | (QS_u32_fmt_(QS_FUN_T, (uint32_t)(fun_))) |
#define QS_SIG | ( | sig_, | |
obj_ | |||
) |
#define QS_SIG_DICTIONARY | ( | sig_, | |
obj_ | |||
) | (QS_sig_dict_pre_((sig_), (obj_), #sig_)) |
Output QS 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.
[in] | sig_ | event signal (typically enumerated, e.g. TIMEOUT_SIG ) |
[in] | obj_ | pointer to the associated state machine object (might be (void*)0 for globally recognized signals) |
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 many state machines (such as globally published signals), you can specify a signal dictionary entry with the obj_
parameter set to (void*)0
.
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):
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:
#define QS_OBJ_DICTIONARY | ( | obj_ | ) | (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.
[in] | obj_ | pointer to the object (any object) |
The following example shows the definition of object dictionary entry for the Table active object:
#define QS_OBJ_ARR_DICTIONARY | ( | obj_, | |
idx_ | |||
) | (QS_obj_arr_dict_pre_((obj_), (idx_), #obj_)) |
Output object-array dictionary record
An object array dictionary record associates the binary address of the object element in the target's memory with the human-readable name of the object.
[in] | obj_ | pointer to the object (any object) |
[in] | idx_ | array index |
The following example shows the definition of object array dictionary for Philo::inst[n]
and Philo::inst[n].m_timeEvt
:
#define QS_FUN_DICTIONARY | ( | fun_ | ) | (QS_fun_dict_pre_((void (*)(void))(fun_), #fun_)) |
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.
#define QS_USR_DICTIONARY | ( | rec_ | ) | (QS_usr_dict_pre_((rec_), #rec_)) |
#define QS_ENUM_DICTIONARY | ( | value_, | |
group_ | |||
) | (QS_enum_dict_pre_((value_), (group_), #value_)) |
#define QF_QS_ACTION | ( | act_ | ) | (act_) |
#define QS_EOD ((uint16_t)0xFFFFU) |
#define QS_CMD ((uint8_t)7U) |
Constant representing command enumeration group in QS_ENUM_DICTIONARY() and QS_ENUM()
#define QS_HEX_FMT ((uint8_t)0x0FU) |
#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.
#define QS_CRIT_E_ | ( | ) | 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.
#define QS_CRIT_X_ | ( | ) | QF_CRIT_EXIT(dummy); QS_REC_DONE() |
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.
#define QS_TEST_PROBE_DEF | ( | fun_ | ) | uint32_t const qs_tp_ = QS_getTestProbe_((void (*)(void))(fun_)); |
#define QS_TEST_PROBE | ( | code_ | ) | if (qs_tp_ != 0U) { code_ } |
#define QS_TEST_PROBE_ID | ( | id_, | |
code_ | |||
) | if (qs_tp_ == (uint32_t)(id_)) { code_ } |
#define QS_TEST_PAUSE | ( | ) | (QS_test_pause_()) |
typedef uint_fast16_t QSCtr |
typedef uint32_t QSTimeCtr |
typedef uint32_t QSFun |
enum QS_preType |
Enumerates data elements for app-specific trace records
void QF_QS_CRIT_ENTRY | ( | void | ) |
Output the critical section entry record
void QF_QS_CRIT_EXIT | ( | void | ) |
Output the critical section exit record
void QF_QS_ISR_ENTRY | ( | uint_fast8_t const | isrnest, |
uint_fast8_t const | prio_ | ||
) |
Output the interrupt entry record
void QF_QS_ISR_EXIT | ( | uint_fast8_t | isrnest, |
uint_fast8_t | prio | ||
) |
Output the ISR exit trace record
void QS_test_pause_ | ( | void | ) |
internal function to pause test and enter the test event loop
uint32_t QS_getTestProbe_ | ( | QSpyFunPtr const | api | ) |
get the test probe data for the given API
void QS_onTestSetup | ( | void | ) |
callback to setup a unit test inside the Target
void QS_onTestTeardown | ( | void | ) |
callback to teardown after a unit test inside the Target
void QS_onTestEvt | ( | QEvt * | e | ) |
callback to "massage" the test event before dispatching/posting it
void QS_onTestPost | ( | void const * | sender, |
QActive * | recipient, | ||
QEvt const * | e, | ||
bool | status | ||
) |
callback to examine an event that is about to be posted
void QS_onTestLoop | ( | void | ) |
callback to run the test loop
void QS_processTestEvts_ | ( | void | ) |
internal function to process posted events during test
|
extern |
the only instance of the QS-TX object (Singleton)
|
extern |
QUTest data