50 struct QS::QSrxPriv QS::rxPriv_;
53 #if (QS_OBJ_PTR_SIZE == 1U)
55 #elif (QS_OBJ_PTR_SIZE == 2U)
57 #elif (QS_OBJ_PTR_SIZE == 4U)
59 #elif (QS_OBJ_PTR_SIZE == 8U)
63 #if (QS_FUN_PTR_SIZE == 1U)
65 #elif (QS_FUN_PTR_SIZE == 2U)
67 #elif (QS_FUN_PTR_SIZE == 4U)
69 #elif (QS_FUN_PTR_SIZE == 8U)
137 static struct ExtState {
191 WAIT4_TEST_SETUP_FRAME,
192 WAIT4_TEST_TEARDOWN_FRAME,
193 WAIT4_TEST_PROBE_DATA,
194 WAIT4_TEST_PROBE_ADDR,
195 WAIT4_TEST_PROBE_FRAME,
196 WAIT4_TEST_CONTINUE_FRAME,
201 static struct TestData {
214 static void rxPoke_(
void) noexcept;
217 static inline void tran_(RxStateEnum
const target) noexcept {
246 rxPriv_.buf = &sto[0];
247 rxPriv_.end =
static_cast<QSCtr>(stoSize);
270 l_testData.tpNum = 0U;
271 l_testData.testTime = 0U;
284 QSCtr head = rxPriv_.head;
285 if (head == rxPriv_.tail) {
288 else if (head < rxPriv_.tail) {
305 rxPriv_.currObj[obj_kind] = obj_ptr;
328 reinterpret_cast<QHsm *
>(
329 QS::rxPriv_.currObj[obj_kind])->getStateHandler());
381 if (l_rx.esc != 0U) {
416 switch (l_rx.state) {
429 tran_(WAIT4_INFO_FRAME);
435 tran_(WAIT4_RESET_FRAME);
438 tran_(WAIT4_TICK_RATE);
442 l_rx.var.peek.offs = 0U;
443 l_rx.var.peek.idx = 0U;
444 tran_(WAIT4_PEEK_OFFS);
458 l_rx.var.poke.offs = 0U;
459 l_rx.var.poke.idx = 0U;
460 tran_(WAIT4_POKE_OFFS);
464 (l_rx.var.poke.fill != 0U)
472 l_rx.var.flt.recId = b;
473 tran_(WAIT4_FILTER_LEN);
477 l_rx.var.obj.recId = b;
478 tran_(WAIT4_OBJ_KIND);
483 tran_(WAIT4_QUERY_KIND);
486 tran_(WAIT4_EVT_PRIO);
491 tran_(WAIT4_TEST_SETUP_FRAME);
494 tran_(WAIT4_TEST_TEARDOWN_FRAME);
497 tran_(WAIT4_TEST_CONTINUE_FRAME);
502 (
sizeof(l_testData.tpBuf)
503 /
sizeof(l_testData.tpBuf[0]))))
505 l_rx.var.tp.data = 0U;
506 l_rx.var.tp.idx = 0U;
507 tran_(WAIT4_TEST_PROBE_DATA);
524 case WAIT4_INFO_FRAME: {
529 l_rx.var.cmd.cmdId = b;
530 l_rx.var.cmd.idx = 0U;
531 l_rx.var.cmd.param1 = 0U;
532 l_rx.var.cmd.param2 = 0U;
533 l_rx.var.cmd.param3 = 0U;
534 tran_(WAIT4_CMD_PARAM1);
537 case WAIT4_CMD_PARAM1: {
538 l_rx.var.cmd.param1 |=
540 l_rx.var.cmd.idx += 8U;
541 if (l_rx.var.cmd.idx == (8U*4U)) {
542 l_rx.var.cmd.idx = 0U;
543 tran_(WAIT4_CMD_PARAM2);
547 case WAIT4_CMD_PARAM2: {
548 l_rx.var.cmd.param2 |=
550 l_rx.var.cmd.idx += 8U;
551 if (l_rx.var.cmd.idx == (8U*4U)) {
552 l_rx.var.cmd.idx = 0U;
553 tran_(WAIT4_CMD_PARAM3);
557 case WAIT4_CMD_PARAM3: {
558 l_rx.var.cmd.param3 |=
560 l_rx.var.cmd.idx += 8U;
561 if (l_rx.var.cmd.idx == (8U*4U)) {
562 l_rx.var.cmd.idx = 0U;
563 tran_(WAIT4_CMD_FRAME);
567 case WAIT4_CMD_FRAME: {
571 case WAIT4_RESET_FRAME: {
575 case WAIT4_TICK_RATE: {
577 tran_(WAIT4_TICK_FRAME);
580 case WAIT4_TICK_FRAME: {
584 case WAIT4_PEEK_OFFS: {
585 if (l_rx.var.peek.idx == 0U) {
587 l_rx.var.peek.idx += 8U;
592 tran_(WAIT4_PEEK_SIZE);
596 case WAIT4_PEEK_SIZE: {
597 if ((b == 1U) || (b == 2U) || (b == 4U)) {
598 l_rx.var.peek.size = b;
599 tran_(WAIT4_PEEK_NUM);
607 case WAIT4_PEEK_NUM: {
608 l_rx.var.peek.num = b;
609 tran_(WAIT4_PEEK_FRAME);
612 case WAIT4_PEEK_FRAME: {
616 case WAIT4_POKE_OFFS: {
617 if (l_rx.var.poke.idx == 0U) {
619 l_rx.var.poke.idx = 1U;
624 tran_(WAIT4_POKE_SIZE);
628 case WAIT4_POKE_SIZE: {
633 l_rx.var.poke.size = b;
634 tran_(WAIT4_POKE_NUM);
644 case WAIT4_POKE_NUM: {
646 l_rx.var.poke.num = b;
647 l_rx.var.poke.data = 0U;
648 l_rx.var.poke.idx = 0U;
649 tran_((l_rx.var.poke.fill != 0U)
661 case WAIT4_FILL_DATA: {
662 l_rx.var.poke.data |=
664 l_rx.var.poke.idx += 8U;
665 if ((l_rx.var.poke.idx >> 3U) == l_rx.var.poke.size) {
666 tran_(WAIT4_FILL_FRAME);
670 case WAIT4_POKE_DATA: {
671 l_rx.var.poke.data |=
673 l_rx.var.poke.idx += 8U;
674 if ((l_rx.var.poke.idx >> 3U) == l_rx.var.poke.size) {
677 if (l_rx.var.poke.num == 0U) {
678 tran_(WAIT4_POKE_FRAME);
683 case WAIT4_FILL_FRAME: {
687 case WAIT4_POKE_FRAME: {
691 case WAIT4_FILTER_LEN: {
692 if (b ==
static_cast<std::uint8_t>(
sizeof(l_rx.var.flt.data))) {
693 l_rx.var.flt.idx = 0U;
694 tran_(WAIT4_FILTER_DATA);
702 case WAIT4_FILTER_DATA: {
703 l_rx.var.flt.data[l_rx.var.flt.idx] = b;
705 if (l_rx.var.flt.idx ==
sizeof(l_rx.var.flt.data)) {
706 tran_(WAIT4_FILTER_FRAME);
710 case WAIT4_FILTER_FRAME: {
714 case WAIT4_OBJ_KIND: {
716 l_rx.var.obj.kind = b;
717 l_rx.var.obj.addr = 0U;
718 l_rx.var.obj.idx = 0U;
719 tran_(WAIT4_OBJ_ADDR);
727 case WAIT4_OBJ_ADDR: {
729 static_cast<QSObj
>(b) << l_rx.var.obj.idx;
730 l_rx.var.obj.idx += 8U;
734 tran_(WAIT4_OBJ_FRAME);
738 case WAIT4_OBJ_FRAME: {
742 case WAIT4_QUERY_KIND: {
744 l_rx.var.obj.kind = b;
745 tran_(WAIT4_QUERY_FRAME);
753 case WAIT4_QUERY_FRAME: {
757 case WAIT4_EVT_PRIO: {
758 l_rx.var.evt.prio = b;
759 l_rx.var.evt.sig = 0U;
760 l_rx.var.evt.idx = 0U;
761 tran_(WAIT4_EVT_SIG);
764 case WAIT4_EVT_SIG: {
765 l_rx.var.evt.sig |=
static_cast<QSignal>(
767 l_rx.var.evt.idx += 8U;
771 l_rx.var.evt.len = 0U;
772 l_rx.var.evt.idx = 0U;
773 tran_(WAIT4_EVT_LEN);
777 case WAIT4_EVT_LEN: {
779 static_cast<unsigned>(b) << l_rx.var.evt.idx);
780 l_rx.var.evt.idx += 8U;
781 if (l_rx.var.evt.idx == (8U * 2U)) {
782 if ((l_rx.var.evt.len +
sizeof(
QEvt))
792 static_cast<enum_t>(l_rx.var.evt.sig));
794 if (l_rx.var.evt.e !=
nullptr) {
797 l_rx.var.evt.p +=
sizeof(
QEvt);
798 if (l_rx.var.evt.len > 0U) {
799 tran_(WAIT4_EVT_PAR);
802 tran_(WAIT4_EVT_FRAME);
817 case WAIT4_EVT_PAR: {
821 if (l_rx.var.evt.len == 0U) {
822 tran_(WAIT4_EVT_FRAME);
826 case WAIT4_EVT_FRAME: {
832 case WAIT4_TEST_SETUP_FRAME: {
836 case WAIT4_TEST_TEARDOWN_FRAME: {
840 case WAIT4_TEST_CONTINUE_FRAME: {
844 case WAIT4_TEST_PROBE_DATA: {
846 (
static_cast<QSFun
>(b) << l_rx.var.tp.idx);
847 l_rx.var.tp.idx += 8U;
849 l_rx.var.tp.addr = 0U;
850 l_rx.var.tp.idx = 0U;
851 tran_(WAIT4_TEST_PROBE_ADDR);
855 case WAIT4_TEST_PROBE_ADDR: {
858 l_rx.var.tp.idx += 8U;
862 tran_(WAIT4_TEST_PROBE_FRAME);
866 case WAIT4_TEST_PROBE_FRAME: {
891 case WAIT4_INFO_FRAME: {
898 case WAIT4_RESET_FRAME: {
903 case WAIT4_CMD_PARAM1:
904 case WAIT4_CMD_PARAM2:
905 case WAIT4_CMD_PARAM3:
906 case WAIT4_CMD_FRAME: {
909 l_rx.var.cmd.param2, l_rx.var.cmd.param3);
916 case WAIT4_TICK_FRAME: {
928 case WAIT4_PEEK_FRAME: {
934 + l_rx.var.peek.offs);
939 for (i = 0U; i < l_rx.var.peek.num; ++i) {
940 switch (l_rx.var.peek.size) {
962 case WAIT4_POKE_DATA: {
967 case WAIT4_POKE_FRAME: {
972 case WAIT4_FILL_FRAME: {
976 + l_rx.var.poke.offs);
977 for (i = 0U; i < l_rx.var.poke.num; ++i) {
978 switch (l_rx.var.poke.size) {
997 case WAIT4_FILTER_FRAME: {
1001 if (l_rx.var.flt.recId
1020 else if (l_rx.var.flt.recId
1036 case WAIT4_OBJ_FRAME: {
1037 i = l_rx.var.obj.kind;
1039 if (l_rx.var.obj.recId
1043 reinterpret_cast<void *
>(l_rx.var.obj.addr);
1046 else if (l_rx.var.obj.recId
1049 if (l_rx.var.obj.addr != 0U) {
1053 l_rx.var.obj.addr)->m_prio);
1069 if (l_rx.var.obj.recId
1083 case WAIT4_QUERY_FRAME: {
1087 case WAIT4_EVT_FRAME: {
1095 if (l_rx.var.evt.prio == 0U) {
1108 else if (l_rx.var.evt.prio == 255U) {
1118 ->dispatch(l_rx.var.evt.e, 0U);
1125 else if (l_rx.var.evt.prio == 254U) {
1135 ->init(l_rx.var.evt.e, 0U);
1142 else if (l_rx.var.evt.prio == 253U) {
1164 if ((i & 1U) != 0U) {
1168 if ((i & 0x80U) != 0U) {
1181 case WAIT4_TEST_SETUP_FRAME: {
1183 l_testData.tpNum = 0U;
1184 l_testData.testTime = 0U;
1190 case WAIT4_TEST_TEARDOWN_FRAME: {
1196 case WAIT4_TEST_CONTINUE_FRAME: {
1202 case WAIT4_TEST_PROBE_FRAME: {
1206 < (
sizeof(l_testData.tpBuf) /
sizeof(l_testData.tpBuf[0])));
1207 l_testData.tpBuf[l_testData.tpNum] = l_rx.var.tp;
1229 case WAIT4_EVT_FRAME: {
1281 + l_rx.var.poke.offs);
1282 switch (l_rx.var.poke.size) {
1291 *
reinterpret_cast<std::uint32_t *
>(ptr) = l_rx.var.poke.data;
1298 l_rx.var.poke.data = 0U;
1299 l_rx.var.poke.idx = 0U;
1300 l_rx.var.poke.offs +=
static_cast<std::uint16_t>(l_rx.var.poke.size);
1321 if (l_testData.tpBuf[i].addr ==
reinterpret_cast<QSFun
>(api)) {
1322 data = l_testData.tpBuf[i].data;
1338 l_testData.tpBuf[j] = l_testData.tpBuf[j + 1U];
1348 return (++l_testData.testTime);
unsigned int uint16_t
exact-width 16-bit unsigned int
unsigned int uint_fast16_t
fast at-least 16-bit unsigned int
unsigned long int uint32_t
exact-width 32-bit unsigned int
signed int int_fast16_t
fast at-least 16-bit signed int
unsigned long long uint64_t
exact-width 64-bit unsigned int
unsigned char uint8_t
exact-width 8-bit unsigned int
unsigned int uint_fast8_t
fast at-least 8-bit unsigned int
QActive active object (based on QP::QHsm implementation)
Native QF Event Queue class.
static void gc(QEvt const *const e) noexcept
Recycle a dynamic event.
static QEvt * newX_(std::uint_fast16_t const evtSize, std::uint_fast16_t const margin, enum_t const sig) noexcept
Internal QF implementation of creating new dynamic event.
static QActive * active_[QF_MAX_ACTIVE+1U]
array of registered active objects
static std::uint_fast16_t poolGetMaxBlockSize(void) noexcept
Obtain the block size of any registered event pools.
static void tickX_(std::uint_fast8_t const tickRate, void const *const sender) noexcept
Processes all armed time events at every clock tick.
static void publish_(QEvt const *const e, void const *const sender, std::uint_fast8_t const qs_id) noexcept
Publish event to the framework.
Hierarchical State Machine base class.
Native QF memory pool class.
void * currObj[MAX_OBJ]
current objects
static struct QP::QS::QSrxPriv rxPriv_
static void setCurrObj(std::uint8_t obj_kind, void *obj_ptr) noexcept
Set the "current object" in the Target.
static QSTimeCtr onGetTime(void)
Callback to obtain a timestamp for a QS record.
static void rxHandleGoodFrame_(std::uint8_t const state)
internal function to handle incoming (QS-RX) packet
static void onTestTeardown(void)
callback to teardown after a unit test inside the Target
static std::uint32_t getTestProbe_(void(*const api)(void)) noexcept
internal function to get the Test-Probe for a given API
static void beginRec_(std::uint_fast8_t const rec) noexcept
Mark the begin of a QS record rec.
static void onTestSetup(void)
callback to setup a unit test inside the Target
@ SM_OBJ
state machine object for QEP
@ TE_OBJ
time event object
@ AP_OBJ
generic Application-specific object
@ MP_OBJ
event pool object
std::uint8_t locFilter[16]
lobal on/off QS filter
static void onReset(void)
callback function to reset the Target (to be implemented in the BSP)
static void endRec_(void) noexcept
Mark the end of a QS record rec.
QSCtr head
offset to where next byte will be inserted
bool inTestLoop
QUTest event loop is running.
static void processTestEvts_(void)
internal function to process posted events during test
QSCtr end
offset of the end of the ring buffer
static std::uint16_t rxGetNfree(void) noexcept
Obtain the number of free bytes in the QS RX data buffer.
static void locFilter_(std::int_fast16_t const filter) noexcept
Set/clear the local Filter for a given object-id.
std::uint8_t glbFilter[16]
global on/off QS filter
static void queryCurrObj(std::uint8_t obj_kind) noexcept
Query the "current object" in the Target.
static void onCommand(std::uint8_t cmdId, std::uint32_t param1, std::uint32_t param2, std::uint32_t param3)
Callback function to execute user commands (to be implemented in BSP)
static void rxInitBuf(std::uint8_t *const sto, std::uint16_t const stoSize) noexcept
Initialize the QS RX data buffer.
QSCtr tail
offset of where next record will be extracted
@ SM_AO_OBJ
combination of SM and AO
static void tickX_(std::uint_fast8_t const tickRate, void const *const sender) noexcept
internal function to process armed time events during test
std::uint8_t * buf
pointer to the start of the ring buffer
static void rxParse(void)
Parse all bytes present in the QS RX data buffer.
static void onTestEvt(QEvt *e)
callback to "massage" the test event before dispatching/posting it
namespace associated with the QP/C++ framework
constexpr std::uint8_t QS_ESC
Escape character of the QS output protocol.
void QS_target_info_(std::uint8_t const isReset) noexcept
send the Target info (object sizes, build time-stamp, QP version)
static void rxReportAck_(enum QSpyRxRecords const recId) noexcept
@ QS_TEST_PROBE_GET
reports that Test-Probe has been used
@ QS_TARGET_DONE
reports completion of a user callback
@ QS_OBJ_DICT
object dictionary entry
@ QS_RX_STATUS
reports QS data receive status
@ QS_QUERY_DATA
reports the data from "current object" query
@ QS_PEEK_DATA
reports the data from the PEEK query
static void rxReportDone_(enum QSpyRxRecords const recId) noexcept
void QF_EVT_REF_CTR_INC_(QEvt const *const e) noexcept
increment the refCtr_ of an event e
static void rxReportError_(std::uint8_t const code) noexcept
static void rxPoke_(void) noexcept
static void rxParseData_(std::uint8_t const b) noexcept
constexpr std::uint8_t QS_ESC_XOR
Escape modifier of the QS output protocol.
static void rxHandleBadFrame_(std::uint8_t const state) noexcept
constexpr std::uint8_t QS_GOOD_CHKSUM
Escape character of the QS output protocol.
std::uint_fast16_t QSCtr
QS ring buffer counter and offset type.
constexpr std::uint8_t QS_FRAME
Frame character of the QS output protocol.
QSpyRxRecords
Quantum Spy Receive (RX) record types.
@ QS_RX_RESET
reset the Target
@ QS_RX_EVENT
inject an event to the Target (post/publish)
@ QS_RX_LOC_FILTER
set local filters in the Target
@ QS_RX_FILL
fill Target memory
@ QS_RX_AO_FILTER
set local AO filter in the Target
@ QS_RX_TICK
call QF_tick()
@ QS_RX_PEEK
peek Target memory
@ QS_RX_CURR_OBJ
set the "current-object" in the Target
@ QS_RX_GLB_FILTER
set global filters in the Target
@ QS_RX_POKE
poke Target memory
@ QS_RX_INFO
query Target info (ver, config, tstamp)
@ QS_RX_TEST_TEARDOWN
test teardown
@ QS_RX_TEST_PROBE
set a Test-Probe in the Target
@ QS_RX_TEST_SETUP
test setup
@ QS_RX_COMMAND
execute a user-defined command in the Target
@ QS_RX_TEST_CONTINUE
continue a test after QS_RX_TEST_WAIT()
@ QS_RX_QUERY_CURR
query the "current object" in the Target
std::uint16_t QSignal
QSignal represents the signal of an event.
Customizable and memory-efficient assertions for embedded systems.
#define Q_DEFINE_THIS_MODULE(name_)
Define the user-specified module name for assertions in this file.
#define Q_ASSERT_ID(id_, test_)
General purpose assertion with user-specified assertion-id.
#define Q_REQUIRE_ID(id_, test_)
Assertion for checking preconditions with user-specified assertion-id.
#define Q_DIM(array_)
Helper macro to calculate static dimension of a 1-dim array_.
#define Q_ERROR_ID(id_)
Assertion with user-specified assertion-id for a wrong path.
int enum_t
alias for enumerations used for event signals
#define Q_SIGNAL_SIZE
The size (in bytes) of the signal of an event. Valid values: 1U, 2U, or 4U; default 2U.
Internal (package scope) QF/C++ interface.
#define QS_CRIT_STAT_
This is an internal macro for defining the critical section status type.
#define QS_REC_DONE()
macro to hook up user code when a QS record is produced
#define QS_CRIT_X_()
This is an internal macro for exiting a critical section.
#define QS_CRIT_E_()
This is an internal macro for entering a critical section.
#define QS_U8_PRE_(data_)
#define QS_OBJ_PRE_(obj_)
#define QS_FUN_PRE_(fun_)
#define QS_MPC_PRE_(ctr_)
#define QS_TEC_PRE_(ctr_)
#define QS_U16_PRE_(data_)
#define QS_SIG_PRE_(sig_)
#define QS_EQC_PRE_(ctr_)
#define QS_U32_PRE_(data_)
Internal (package scope) QS/C++ interface.
#define QS_STR_PRE_(msg_)
Internal QS macro to output a zero-terminated ASCII string data element.
QS/C++ port to a 32-bit CPU, generic compiler.
#define QF_MAX_ACTIVE
The maximum number of active objects in the application.