QS-RX adaptation for MPU isolation
This commit is contained in:
MMS 2024-02-21 16:39:54 -05:00
parent 0150f5a22b
commit fcea9943bb
8 changed files with 817 additions and 783 deletions

@ -1 +1 @@
Subproject commit 570aa85d0863afab4ffe87ba4b2a32814de691ba Subproject commit 9c903f815f7690385c69e326fd8c1cc1f100ce4a

View File

@ -162,7 +162,7 @@ static inline void QF_psInit(
//! @deprecated begin of a user QS record, instead use QS_BEGIN_ID() //! @deprecated begin of a user QS record, instead use QS_BEGIN_ID()
#define QS_BEGIN(rec_, obj_) \ #define QS_BEGIN(rec_, obj_) \
if (((QS_filt_.glb[(uint_fast8_t)(rec_) >> 3U] \ if (((QS_filt_.glb[(uint_fast8_t)(rec_) >> 3U] \
& (1U << ((uint_fast8_t)(rec_) & 7U))) != 0U) \ & (1U << ((uint_fast8_t)(rec_) & 7U))) != 0U) \
&& ((QS_priv_.locFilter_AP == (void *)0) \ && ((QS_priv_.locFilter_AP == (void *)0) \
|| (QS_priv_.locFilter_AP == (obj_)))) \ || (QS_priv_.locFilter_AP == (obj_)))) \

View File

@ -255,6 +255,36 @@ enum QSpyIdGroups {
//! @struct QSpyId //! @struct QSpyId
typedef struct { uint8_t prio; } QSpyId; typedef struct { uint8_t prio; } QSpyId;
//${QS::types::QSObj} ........................................................
#if (QS_OBJ_PTR_SIZE == 2U)
typedef uint16_t QSObj;
#endif // (QS_OBJ_PTR_SIZE == 2U)
//${QS::types::QSObj} ........................................................
#if (QS_OBJ_PTR_SIZE == 4U)
typedef uint32_t QSObj;
#endif // (QS_OBJ_PTR_SIZE == 4U)
//${QS::types::QSObj} ........................................................
#if (QS_OBJ_PTR_SIZE == 8U)
typedef uint64_t QSObj;
#endif // (QS_OBJ_PTR_SIZE == 8U)
//${QS::types::QSFun} ........................................................
#if (QS_FUN_PTR_SIZE == 2U)
typedef uint16_t QSFun;
#endif // (QS_FUN_PTR_SIZE == 2U)
//${QS::types::QSFun} ........................................................
#if (QS_FUN_PTR_SIZE == 4U)
typedef uint32_t QSFun;
#endif // (QS_FUN_PTR_SIZE == 4U)
//${QS::types::QSFun} ........................................................
#if (QS_FUN_PTR_SIZE == 8U)
typedef uint64_t QSFun;
#endif // (QS_FUN_PTR_SIZE == 8U)
//${QS::types::QSpyFunPtr} ................................................... //${QS::types::QSpyFunPtr} ...................................................
//! @static @private @memberof QS //! @static @private @memberof QS
typedef void (* QSpyFunPtr )(void); typedef void (* QSpyFunPtr )(void);
@ -278,21 +308,6 @@ typedef uint16_t QSTimeCtr;
#if (QS_TIME_SIZE == 4U) #if (QS_TIME_SIZE == 4U)
typedef uint32_t QSTimeCtr; typedef uint32_t QSTimeCtr;
#endif // (QS_TIME_SIZE == 4U) #endif // (QS_TIME_SIZE == 4U)
//${QS::types::QSFun} ........................................................
#if (QS_FUN_PTR_SIZE == 2U)
typedef uint16_t QSFun;
#endif // (QS_FUN_PTR_SIZE == 2U)
//${QS::types::QSFun} ........................................................
#if (QS_FUN_PTR_SIZE == 4U)
typedef uint32_t QSFun;
#endif // (QS_FUN_PTR_SIZE == 4U)
//${QS::types::QSFun} ........................................................
#if (QS_FUN_PTR_SIZE == 8U)
typedef uint64_t QSFun;
#endif // (QS_FUN_PTR_SIZE == 8U)
//$enddecl${QS::types} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //$enddecl${QS::types} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$declare${QS::filters} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv //$declare${QS::filters} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
@ -599,63 +614,33 @@ void QS_beginRec_(uint_fast8_t const rec);
void QS_endRec_(void); void QS_endRec_(void);
void QS_u8_raw_(uint8_t const d); void QS_u8_raw_(uint8_t const d);
void QS_2u8_raw_( void QS_2u8_raw_(uint8_t const d1, uint8_t const d2);
uint8_t const d1,
uint8_t const d2);
void QS_u16_raw_(uint16_t const d); void QS_u16_raw_(uint16_t const d);
void QS_u32_raw_(uint32_t const d); void QS_u32_raw_(uint32_t const d);
void QS_u64_raw_(uint64_t const d); void QS_u64_raw_(uint64_t const d);
void QS_obj_raw_(void const * const obj); void QS_obj_raw_(void const * const obj);
void QS_str_raw_(char const * const str); void QS_str_raw_(char const * const str);
void QS_u8_fmt_( void QS_u8_fmt_(uint8_t const format, uint8_t const d);
uint8_t const format, void QS_u16_fmt_(uint8_t const format, uint16_t const d);
uint8_t const d); void QS_u32_fmt_(uint8_t const format, uint32_t const d);
void QS_u16_fmt_( void QS_u64_fmt_(uint8_t const format, uint64_t const d);
uint8_t const format, void QS_f32_fmt_(uint8_t const format, float32_t const f);
uint16_t const d); void QS_f64_fmt_(uint8_t const format, float64_t const d);
void QS_u32_fmt_(
uint8_t const format,
uint32_t const d);
void QS_u64_fmt_(
uint8_t const format,
uint64_t const d);
void QS_f32_fmt_(
uint8_t const format,
float32_t const f);
void QS_f64_fmt_(
uint8_t const format,
float64_t const d);
void QS_str_fmt_(char const * const str); void QS_str_fmt_(char const * const str);
void QS_mem_fmt_( void QS_mem_fmt_(uint8_t const * const blk, uint8_t const size);
uint8_t const * const blk,
uint8_t const size);
void QS_sig_dict_pre_( void QS_sig_dict_pre_(QSignal const sig, void const * const obj,
QSignal const sig,
void const * const obj,
char const * const name); char const * const name);
void QS_obj_dict_pre_( void QS_obj_dict_pre_(void const * const obj, char const * const name);
void const * const obj, void QS_obj_arr_dict_pre_(void const * const obj, uint_fast16_t const idx,
char const * const name); char const * const name);
void QS_obj_arr_dict_pre_( void QS_fun_dict_pre_(QSpyFunPtr const fun, char const * const name);
void const * const obj, void QS_usr_dict_pre_(enum_t const rec, char const * const name);
uint_fast16_t const idx, void QS_enum_dict_pre_(enum_t const value, uint8_t const group,
char const * const name);
void QS_fun_dict_pre_(
QSpyFunPtr const fun,
char const * const name);
void QS_usr_dict_pre_(
enum_t const rec,
char const * const name);
void QS_enum_dict_pre_(
enum_t const value,
uint8_t const group,
char const * const name); char const * const name);
void QS_assertion_pre_( void QS_assertion_pre_(char const * const module, int_t const id,
char const * const module,
int_t const id,
uint32_t const delay); uint32_t const delay);
void QS_target_info_pre_(uint8_t const isReset); void QS_target_info_pre_(uint8_t const isReset);
@ -720,105 +705,6 @@ void QS_onFlush(void);
QSTimeCtr QS_onGetTime(void); QSTimeCtr QS_onGetTime(void);
//$enddecl${QS::QS-TX} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //$enddecl${QS::QS-TX} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//============================================================================
//! @cond INTERNAL
typedef struct {
void * currObj[8];
uint8_t * buf;
QSCtr end;
QSCtr volatile head;
QSCtr volatile tail;
#ifdef Q_UTEST
bool inTestLoop;
#endif
} QS_RxAttr;
//! @static @private @memberof QS
extern QS_RxAttr QS_rxPriv_;
//! @endcond
//============================================================================
//$declare${QS::QS-RX} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${QS::QS-RX::QSpyObjKind} ..................................................
//! @static @public @memberof QS
//! Kinds of objects used in QS-RX
enum QS_QSpyObjKind {
SM_OBJ, //!< state machine object
AO_OBJ, //!< active object
MP_OBJ, //!< event pool object
EQ_OBJ, //!< raw queue object
TE_OBJ, //!< time event object
AP_OBJ, //!< generic Application-specific object
MAX_OBJ
};
//${QS::QS-RX::OSpyObjComb} ..................................................
//! @static @public @memberof QS
//! Object combinations for QS-RX
enum QS_OSpyObjComb {
SM_AO_OBJ = (enum_t)MAX_OBJ //!< combination of SM and AO
};
//${QS::QS-RX::rxInitBuf} ....................................................
//! @static @public @memberof QS
void QS_rxInitBuf(
uint8_t * const sto,
uint16_t const stoSize);
//${QS::QS-RX::rxPut} ........................................................
//! @static @public @memberof QS
static inline bool QS_rxPut(uint8_t const b) {
// NOTE: does not need critical section
// But requires system-level memory access (QF_MEM_SYS()).
QSCtr head = QS_rxPriv_.head + 1U;
if (head == QS_rxPriv_.end) {
head = 0U;
}
if (head != QS_rxPriv_.tail) { // buffer NOT full?
QS_rxPriv_.buf[QS_rxPriv_.head] = b;
QS_rxPriv_.head = head; // update the head to a *valid* index
return true; // byte placed in the buffer
}
else {
return false; // byte NOT placed in the buffer
}
}
//${QS::QS-RX::rxParse} ......................................................
//! @static @public @memberof QS
void QS_rxParse(void);
//${QS::QS-RX::setCurrObj} ...................................................
//! @static @public @memberof QS
void QS_setCurrObj(
uint8_t const obj_kind,
void * const obj_ptr);
//${QS::QS-RX::rxGetNfree} ...................................................
//! @static @public @memberof QS
uint16_t QS_rxGetNfree(void);
//${QS::QS-RX::doInput} ......................................................
//! @static @public @memberof QS
void QS_doInput(void);
//${QS::QS-RX::onReset} ......................................................
//! @static @public @memberof QS
void QS_onReset(void);
//${QS::QS-RX::onCommand} ....................................................
//! @static @public @memberof QS
void QS_onCommand(
uint8_t cmdId,
uint32_t param1,
uint32_t param2,
uint32_t param3);
//$enddecl${QS::QS-RX} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//============================================================================ //============================================================================
#ifdef Q_UTEST #ifdef Q_UTEST
@ -978,4 +864,170 @@ void QActiveDummy_fakePostLIFO_(
#endif // Q_UTEST #endif // Q_UTEST
//============================================================================
//! @cond INTERNAL
typedef struct {
uint32_t param1;
uint32_t param2;
uint32_t param3;
uint8_t idx;
uint8_t cmdId;
} CmdVar;
typedef struct {
uint_fast8_t rate;
} TickVar;
typedef struct {
uint16_t offs;
uint8_t size;
uint8_t num;
uint8_t idx;
} PeekVar;
typedef struct {
uint32_t data;
uint16_t offs;
uint8_t size;
uint8_t num;
uint8_t idx;
uint8_t fill;
} PokeVar;
typedef struct {
uint8_t data[16];
uint8_t idx;
int8_t recId; // global/local
} FltVar;
typedef struct {
QSObj addr;
uint8_t idx;
uint8_t kind; // see qs.h, enum QSpyObjKind
int8_t recId;
} ObjVar;
typedef struct {
QEvt *e;
uint8_t *p;
QSignal sig;
uint16_t len;
uint8_t prio;
uint8_t idx;
} EvtVar;
typedef struct {
void * currObj[8];
uint8_t * buf;
QSCtr end;
QSCtr volatile head;
QSCtr volatile tail;
uint8_t state;
uint8_t esc;
uint8_t seq;
uint8_t chksum;
#ifdef Q_UTEST
bool inTestLoop;
#endif
union Variant {
CmdVar cmd;
TickVar tick;
PeekVar peek;
PokeVar poke;
FltVar flt;
ObjVar obj;
EvtVar evt;
#ifdef Q_UTEST
struct QS_TProbe tp;
#endif // Q_UTEST
} var;
} QS_RxAttr;
//! @endcond
//! @static @private @memberof QS
extern QS_RxAttr QS_rxPriv_;
//============================================================================
//$declare${QS::QS-RX} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${QS::QS-RX::QSpyObjKind} ..................................................
//! @static @public @memberof QS
//! Kinds of objects used in QS-RX
enum QS_QSpyObjKind {
SM_OBJ, //!< state machine object
AO_OBJ, //!< active object
MP_OBJ, //!< event pool object
EQ_OBJ, //!< raw queue object
TE_OBJ, //!< time event object
AP_OBJ, //!< generic Application-specific object
MAX_OBJ
};
//${QS::QS-RX::OSpyObjComb} ..................................................
//! @static @public @memberof QS
//! Object combinations for QS-RX
enum QS_OSpyObjComb {
SM_AO_OBJ = (enum_t)MAX_OBJ //!< combination of SM and AO
};
//${QS::QS-RX::rxInitBuf} ....................................................
//! @static @public @memberof QS
void QS_rxInitBuf(
uint8_t * const sto,
uint16_t const stoSize);
//${QS::QS-RX::rxPut} ........................................................
//! @static @public @memberof QS
static inline bool QS_rxPut(uint8_t const b) {
// NOTE: does not need critical section
// But requires system-level memory access (QF_MEM_SYS()).
QSCtr head = QS_rxPriv_.head + 1U;
if (head == QS_rxPriv_.end) {
head = 0U;
}
if (head != QS_rxPriv_.tail) { // buffer NOT full?
QS_rxPriv_.buf[QS_rxPriv_.head] = b;
QS_rxPriv_.head = head; // update the head to a *valid* index
return true; // byte placed in the buffer
}
else {
return false; // byte NOT placed in the buffer
}
}
//${QS::QS-RX::rxParse} ......................................................
//! @static @public @memberof QS
void QS_rxParse(void);
//${QS::QS-RX::setCurrObj} ...................................................
//! @static @public @memberof QS
void QS_setCurrObj(
uint8_t const obj_kind,
void * const obj_ptr);
//${QS::QS-RX::rxGetNfree} ...................................................
//! @static @public @memberof QS
uint16_t QS_rxGetNfree(void);
//${QS::QS-RX::doInput} ......................................................
//! @static @public @memberof QS
void QS_doInput(void);
//${QS::QS-RX::onReset} ......................................................
//! @static @public @memberof QS
void QS_onReset(void);
//${QS::QS-RX::onCommand} ....................................................
//! @static @public @memberof QS
void QS_onCommand(
uint8_t cmdId,
uint32_t param1,
uint32_t param2,
uint32_t param3);
//$enddecl${QS::QS-RX} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#endif // QS_H_ #endif // QS_H_

12
qpc.md5
View File

@ -1,11 +1,11 @@
d5ba3887b906752cca7a049ef063f0d0 *qpc.qm 13078bbbcfe973eb8adb284ddccb74c7 *qpc.qm
f71fdc0261b7d7e1693f7cf92b269fc0 *include/qequeue.h f71fdc0261b7d7e1693f7cf92b269fc0 *include/qequeue.h
57b1efebccde23a26f9d11e822ec379f *include/qk.h 57b1efebccde23a26f9d11e822ec379f *include/qk.h
807f80a7a39be52083010803f76b4f05 *include/qmpool.h 807f80a7a39be52083010803f76b4f05 *include/qmpool.h
48125adc82b65fdfa09dfbddd2621ec3 *include/qp.h 48125adc82b65fdfa09dfbddd2621ec3 *include/qp.h
e7b6c999b10d91f5c1adf1fde500e452 *include/qp_pkg.h e7b6c999b10d91f5c1adf1fde500e452 *include/qp_pkg.h
37d55c70130d7829f2b7a25c900e9512 *include/qpc.h 78847559ac0addc557e6984c6cb93474 *include/qpc.h
3959cc72ed87173427adfb81a11dd862 *include/qs.h 2f2ed281e63d5803738ab0c92a77171f *include/qs.h
66f8bd1303a72346f52fbcccfd363586 *include/qs_dummy.h 66f8bd1303a72346f52fbcccfd363586 *include/qs_dummy.h
fad2d5ccd173e6374f4bce243709eef7 *include/qs_pkg.h fad2d5ccd173e6374f4bce243709eef7 *include/qs_pkg.h
c33f022827668e991f2b9f212493036e *include/qsafe.h c33f022827668e991f2b9f212493036e *include/qsafe.h
@ -18,7 +18,7 @@ a25152f319178420b5b5140ca51ea4ae *src/qf/CMakeLists.txt
762cba96738f7e3fe4ebd66659542b30 *src/qf/qf_act.c 762cba96738f7e3fe4ebd66659542b30 *src/qf/qf_act.c
78ad6e00669d2888ceef6e6d84e83e55 *src/qf/qf_actq.c 78ad6e00669d2888ceef6e6d84e83e55 *src/qf/qf_actq.c
858f4abf264ab69734b4df56b0bfa739 *src/qf/qf_defer.c 858f4abf264ab69734b4df56b0bfa739 *src/qf/qf_defer.c
6b6af500d498521cb754651ba7118f03 *src/qf/qf_dyn.c 3f25992d60f701951f0d20c1c2e3ad5a *src/qf/qf_dyn.c
bc3e5d7fcb172fee6881f993160502eb *src/qf/qf_mem.c bc3e5d7fcb172fee6881f993160502eb *src/qf/qf_mem.c
4642cd0eaf88ca3012439bb95a43d8b8 *src/qf/qf_ps.c 4642cd0eaf88ca3012439bb95a43d8b8 *src/qf/qf_ps.c
5a1d0999864f48a688d34e9273868e8b *src/qf/qf_qact.c 5a1d0999864f48a688d34e9273868e8b *src/qf/qf_qact.c
@ -28,10 +28,10 @@ b0531b1989555c6b7d128e112f4f3c39 *src/qf/qf_time.c
a8fb5148cc628738ab7bf073e7fe2cdd *src/qk/CMakeLists.txt a8fb5148cc628738ab7bf073e7fe2cdd *src/qk/CMakeLists.txt
f5b5ef77f45d50a6450efd85995287c7 *src/qk/qk.c f5b5ef77f45d50a6450efd85995287c7 *src/qk/qk.c
a9fac3a677755efae96fc84c15acd587 *src/qs/CMakeLists.txt a9fac3a677755efae96fc84c15acd587 *src/qs/CMakeLists.txt
ce79546bbd75aa7d1b5cb60ef0868d92 *src/qs/qs.c e045ce8b2fc053d068ec3eb10c9f65bf *src/qs/qs.c
9091ffd15f7ec791076091bb17eec5fc *src/qs/qs_64bit.c 9091ffd15f7ec791076091bb17eec5fc *src/qs/qs_64bit.c
730d9bea159722e5d2c225e01b5c7875 *src/qs/qs_fp.c 730d9bea159722e5d2c225e01b5c7875 *src/qs/qs_fp.c
23f5a72fc72abde8425900b795cdf0f7 *src/qs/qs_rx.c 60453f6d2b1f915e6e477cca68cb7fee *src/qs/qs_rx.c
80a31dfc0e24839342fe193779401e7b *src/qs/qstamp.c 80a31dfc0e24839342fe193779401e7b *src/qs/qstamp.c
53ab2ae396c90e41045b019cdfea21b5 *src/qs/qutest.c 53ab2ae396c90e41045b019cdfea21b5 *src/qs/qutest.c
f2661d91230a78b9c515f53a70dd81a4 *src/qv/CMakeLists.txt f2661d91230a78b9c515f53a70dd81a4 *src/qv/CMakeLists.txt

705
qpc.qm

File diff suppressed because it is too large Load Diff

View File

@ -104,7 +104,15 @@ void QF_poolInit(
//${QF::QF-dyn::poolGetMaxBlockSize} ......................................... //${QF::QF-dyn::poolGetMaxBlockSize} .........................................
//! @static @public @memberof QF //! @static @public @memberof QF
uint_fast16_t QF_poolGetMaxBlockSize(void) { uint_fast16_t QF_poolGetMaxBlockSize(void) {
return QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[QF_priv_.maxPool_ - 1U]); QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
uint_fast16_t const max_size =
QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[QF_priv_.maxPool_ - 1U]);
QF_MEM_APP();
QF_CRIT_EXIT();
return max_size;
} }
//${QF::QF-dyn::getPoolMin} .................................................. //${QF::QF-dyn::getPoolMin} ..................................................

View File

@ -150,6 +150,7 @@ uint8_t const * QS_getBlock(uint16_t * const pNbytes) {
//$define${QS::filters} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv //$define${QS::filters} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${QS::filters::filt_} ...................................................... //${QS::filters::filt_} ......................................................
//! @static @private @memberof QS
QS_Filter QS_filt_; QS_Filter QS_filt_;
//$enddef${QS::filters} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //$enddef${QS::filters} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#endif #endif

View File

@ -50,89 +50,6 @@
Q_DEFINE_THIS_MODULE("qs_rx") Q_DEFINE_THIS_MODULE("qs_rx")
#if (QS_OBJ_PTR_SIZE == 1U)
typedef uint8_t QSObj;
#elif (QS_OBJ_PTR_SIZE == 2U)
typedef uint16_t QSObj;
#elif (QS_OBJ_PTR_SIZE == 4U)
typedef uint32_t QSObj;
#elif (QS_OBJ_PTR_SIZE == 8U)
typedef uint64_t QSObj;
#endif
typedef struct {
uint32_t param1;
uint32_t param2;
uint32_t param3;
uint8_t idx;
uint8_t cmdId;
} CmdVar;
typedef struct {
uint_fast8_t rate;
} TickVar;
typedef struct {
uint16_t offs;
uint8_t size;
uint8_t num;
uint8_t idx;
} PeekVar;
typedef struct {
uint32_t data;
uint16_t offs;
uint8_t size;
uint8_t num;
uint8_t idx;
uint8_t fill;
} PokeVar;
typedef struct {
uint8_t data[16];
uint8_t idx;
int8_t recId; // global/local
} FltVar;
typedef struct {
QSObj addr;
uint8_t idx;
uint8_t kind; // see qs.h, enum QSpyObjKind
int8_t recId;
} ObjVar;
typedef struct {
QEvt *e;
uint8_t *p;
QSignal sig;
uint16_t len;
uint8_t prio;
uint8_t idx;
} EvtVar;
//! extended-state variables for the current state
//!
//! @trace
//! - @tr{DVR-QS-MC4-R19_02}
static struct {
union Variant {
CmdVar cmd;
TickVar tick;
PeekVar peek;
PokeVar poke;
FltVar flt;
ObjVar obj;
EvtVar evt;
#ifdef Q_UTEST
struct QS_TProbe tp;
#endif // Q_UTEST
} var;
uint8_t state;
uint8_t esc;
uint8_t seq;
uint8_t chksum;
} l_rx;
enum { enum {
ERROR_STATE, ERROR_STATE,
WAIT4_SEQ, WAIT4_SEQ,
@ -193,9 +110,12 @@ static void QS_queryCurrObj(uint8_t const obj_kind);
static void QS_rxPoke_(void); static void QS_rxPoke_(void);
//! Internal QS-RX macro to encapsulate tran. in the QS-RX FSM //! Internal QS-RX macro to encapsulate tran. in the QS-RX FSM
#define QS_RX_TRAN_(target_) (l_rx.state = (uint8_t)(target_)) #define QS_RX_TRAN_(target_) (QS_rxPriv_.state = (uint8_t)(target_))
#ifndef QF_MEM_ISOLATE
//! @static @private @memberof QS
QS_RxAttr QS_rxPriv_; QS_RxAttr QS_rxPriv_;
#endif // QF_MEM_ISOLATE
//! @endcond //! @endcond
//============================================================================ //============================================================================
@ -228,9 +148,9 @@ void QS_rxInitBuf(
QS_rxPriv_.currObj[AP_OBJ] = (void *)0; QS_rxPriv_.currObj[AP_OBJ] = (void *)0;
QS_RX_TRAN_(WAIT4_SEQ); QS_RX_TRAN_(WAIT4_SEQ);
l_rx.esc = 0U; QS_rxPriv_.esc = 0U;
l_rx.seq = 0U; QS_rxPriv_.seq = 0U;
l_rx.chksum = 0U; QS_rxPriv_.chksum = 0U;
QS_beginRec_((uint_fast8_t)QS_OBJ_DICT); QS_beginRec_((uint_fast8_t)QS_OBJ_DICT);
QS_OBJ_PRE_(&QS_rxPriv_); QS_OBJ_PRE_(&QS_rxPriv_);
@ -247,9 +167,6 @@ void QS_rxInitBuf(
//${QS::QS-RX::rxParse} ...................................................... //${QS::QS-RX::rxParse} ......................................................
//! @static @public @memberof QS //! @static @public @memberof QS
void QS_rxParse(void) { void QS_rxParse(void) {
// NOTE: Must be called IN critical section.
// Also requires system-level memory access (QF_MEM_SYS()).
QSCtr tail = QS_rxPriv_.tail; QSCtr tail = QS_rxPriv_.tail;
while (QS_rxPriv_.head != tail) { // QS-RX buffer NOT empty? while (QS_rxPriv_.head != tail) { // QS-RX buffer NOT empty?
uint8_t b = QS_rxPriv_.buf[tail]; uint8_t b = QS_rxPriv_.buf[tail];
@ -260,34 +177,34 @@ void QS_rxParse(void) {
} }
QS_rxPriv_.tail = tail; // update the tail to a *valid* index QS_rxPriv_.tail = tail; // update the tail to a *valid* index
if (l_rx.esc != 0U) { // escaped byte arrived? if (QS_rxPriv_.esc != 0U) { // escaped byte arrived?
l_rx.esc = 0U; QS_rxPriv_.esc = 0U;
b ^= QS_ESC_XOR; b ^= QS_ESC_XOR;
l_rx.chksum += b; QS_rxPriv_.chksum += b;
QS_rxParseData_(b); QS_rxParseData_(b);
} }
else if (b == QS_ESC) { else if (b == QS_ESC) {
l_rx.esc = 1U; QS_rxPriv_.esc = 1U;
} }
else if (b == QS_FRAME) { else if (b == QS_FRAME) {
// get ready for the next frame // get ready for the next frame
b = l_rx.state; // save the current state in b b = QS_rxPriv_.state; // save the current state in b
l_rx.esc = 0U; QS_rxPriv_.esc = 0U;
QS_RX_TRAN_(WAIT4_SEQ); QS_RX_TRAN_(WAIT4_SEQ);
if (l_rx.chksum == QS_GOOD_CHKSUM) { if (QS_rxPriv_.chksum == QS_GOOD_CHKSUM) {
l_rx.chksum = 0U; QS_rxPriv_.chksum = 0U;
QS_rxHandleGoodFrame_(b); QS_rxHandleGoodFrame_(b);
} }
else { // bad checksum else { // bad checksum
l_rx.chksum = 0U; QS_rxPriv_.chksum = 0U;
QS_rxReportError_(0x41); QS_rxReportError_(0x41);
QS_rxHandleBadFrame_(b); QS_rxHandleBadFrame_(b);
} }
} }
else { else {
l_rx.chksum += b; QS_rxPriv_.chksum += b;
QS_rxParseData_(b); QS_rxParseData_(b);
} }
} }
@ -337,12 +254,12 @@ uint16_t QS_rxGetNfree(void) {
//! @cond INTERNAL //! @cond INTERNAL
static void QS_rxParseData_(uint8_t const b) { static void QS_rxParseData_(uint8_t const b) {
switch (l_rx.state) { switch (QS_rxPriv_.state) {
case (uint8_t)WAIT4_SEQ: { case (uint8_t)WAIT4_SEQ: {
++l_rx.seq; ++QS_rxPriv_.seq;
if (l_rx.seq != b) { if (QS_rxPriv_.seq != b) {
QS_rxReportError_(0x42); QS_rxReportError_(0x42);
l_rx.seq = b; // update the sequence QS_rxPriv_.seq = b; // update the sequence
} }
QS_RX_TRAN_(WAIT4_REC); QS_RX_TRAN_(WAIT4_REC);
break; break;
@ -363,8 +280,8 @@ static void QS_rxParseData_(uint8_t const b) {
break; break;
case (uint8_t)QS_RX_PEEK: case (uint8_t)QS_RX_PEEK:
if (QS_rxPriv_.currObj[AP_OBJ] != (void *)0) { if (QS_rxPriv_.currObj[AP_OBJ] != (void *)0) {
l_rx.var.peek.offs = 0U; QS_rxPriv_.var.peek.offs = 0U;
l_rx.var.peek.idx = 0U; QS_rxPriv_.var.peek.idx = 0U;
QS_RX_TRAN_(WAIT4_PEEK_OFFS); QS_RX_TRAN_(WAIT4_PEEK_OFFS);
} }
else { else {
@ -374,15 +291,15 @@ static void QS_rxParseData_(uint8_t const b) {
break; break;
case (uint8_t)QS_RX_POKE: // intentionally fall-through case (uint8_t)QS_RX_POKE: // intentionally fall-through
case (uint8_t)QS_RX_FILL: case (uint8_t)QS_RX_FILL:
l_rx.var.poke.fill = QS_rxPriv_.var.poke.fill =
((b == (uint8_t)QS_RX_FILL) ? 1U : 0U); ((b == (uint8_t)QS_RX_FILL) ? 1U : 0U);
if (QS_rxPriv_.currObj[AP_OBJ] != (void *)0) { if (QS_rxPriv_.currObj[AP_OBJ] != (void *)0) {
l_rx.var.poke.offs = 0U; QS_rxPriv_.var.poke.offs = 0U;
l_rx.var.poke.idx = 0U; QS_rxPriv_.var.poke.idx = 0U;
QS_RX_TRAN_(WAIT4_POKE_OFFS); QS_RX_TRAN_(WAIT4_POKE_OFFS);
} }
else { else {
QS_rxReportError_((l_rx.var.poke.fill != 0U) QS_rxReportError_((QS_rxPriv_.var.poke.fill != 0U)
? (int8_t)QS_RX_FILL ? (int8_t)QS_RX_FILL
: (int8_t)QS_RX_POKE); : (int8_t)QS_RX_POKE);
QS_RX_TRAN_(ERROR_STATE); QS_RX_TRAN_(ERROR_STATE);
@ -390,16 +307,16 @@ static void QS_rxParseData_(uint8_t const b) {
break; break;
case (uint8_t)QS_RX_GLB_FILTER: // intentionally fall-through case (uint8_t)QS_RX_GLB_FILTER: // intentionally fall-through
case (uint8_t)QS_RX_LOC_FILTER: case (uint8_t)QS_RX_LOC_FILTER:
l_rx.var.flt.recId = (int8_t)b; QS_rxPriv_.var.flt.recId = (int8_t)b;
QS_RX_TRAN_(WAIT4_FILTER_LEN); QS_RX_TRAN_(WAIT4_FILTER_LEN);
break; break;
case (uint8_t)QS_RX_AO_FILTER: // intentionally fall-through case (uint8_t)QS_RX_AO_FILTER: // intentionally fall-through
case (uint8_t)QS_RX_CURR_OBJ: case (uint8_t)QS_RX_CURR_OBJ:
l_rx.var.obj.recId = (int8_t)b; QS_rxPriv_.var.obj.recId = (int8_t)b;
QS_RX_TRAN_(WAIT4_OBJ_KIND); QS_RX_TRAN_(WAIT4_OBJ_KIND);
break; break;
case (uint8_t)QS_RX_QUERY_CURR: case (uint8_t)QS_RX_QUERY_CURR:
l_rx.var.obj.recId = (int8_t)QS_RX_QUERY_CURR; QS_rxPriv_.var.obj.recId = (int8_t)QS_RX_QUERY_CURR;
QS_RX_TRAN_(WAIT4_QUERY_KIND); QS_RX_TRAN_(WAIT4_QUERY_KIND);
break; break;
case (uint8_t)QS_RX_EVENT: case (uint8_t)QS_RX_EVENT:
@ -421,8 +338,8 @@ static void QS_rxParseData_(uint8_t const b) {
< (uint8_t)(sizeof(QS_tstPriv_.tpBuf) < (uint8_t)(sizeof(QS_tstPriv_.tpBuf)
/ sizeof(QS_tstPriv_.tpBuf[0]))) / sizeof(QS_tstPriv_.tpBuf[0])))
{ {
l_rx.var.tp.data = 0U; QS_rxPriv_.var.tp.data = 0U;
l_rx.var.tp.idx = 0U; QS_rxPriv_.var.tp.idx = 0U;
QS_RX_TRAN_(WAIT4_TEST_PROBE_DATA); QS_RX_TRAN_(WAIT4_TEST_PROBE_DATA);
} }
else { // the # Test-Probes exceeded else { // the # Test-Probes exceeded
@ -444,37 +361,37 @@ static void QS_rxParseData_(uint8_t const b) {
break; break;
} }
case (uint8_t)WAIT4_CMD_ID: { case (uint8_t)WAIT4_CMD_ID: {
l_rx.var.cmd.cmdId = b; QS_rxPriv_.var.cmd.cmdId = b;
l_rx.var.cmd.idx = 0U; QS_rxPriv_.var.cmd.idx = 0U;
l_rx.var.cmd.param1 = 0U; QS_rxPriv_.var.cmd.param1 = 0U;
l_rx.var.cmd.param2 = 0U; QS_rxPriv_.var.cmd.param2 = 0U;
l_rx.var.cmd.param3 = 0U; QS_rxPriv_.var.cmd.param3 = 0U;
QS_RX_TRAN_(WAIT4_CMD_PARAM1); QS_RX_TRAN_(WAIT4_CMD_PARAM1);
break; break;
} }
case (uint8_t)WAIT4_CMD_PARAM1: { case (uint8_t)WAIT4_CMD_PARAM1: {
l_rx.var.cmd.param1 |= ((uint32_t)b << l_rx.var.cmd.idx); QS_rxPriv_.var.cmd.param1 |= ((uint32_t)b << QS_rxPriv_.var.cmd.idx);
l_rx.var.cmd.idx += 8U; QS_rxPriv_.var.cmd.idx += 8U;
if (l_rx.var.cmd.idx == (8U * 4U)) { if (QS_rxPriv_.var.cmd.idx == (8U * 4U)) {
l_rx.var.cmd.idx = 0U; QS_rxPriv_.var.cmd.idx = 0U;
QS_RX_TRAN_(WAIT4_CMD_PARAM2); QS_RX_TRAN_(WAIT4_CMD_PARAM2);
} }
break; break;
} }
case (uint8_t)WAIT4_CMD_PARAM2: { case (uint8_t)WAIT4_CMD_PARAM2: {
l_rx.var.cmd.param2 |= ((uint32_t)b << l_rx.var.cmd.idx); QS_rxPriv_.var.cmd.param2 |= ((uint32_t)b << QS_rxPriv_.var.cmd.idx);
l_rx.var.cmd.idx += 8U; QS_rxPriv_.var.cmd.idx += 8U;
if (l_rx.var.cmd.idx == (8U * 4U)) { if (QS_rxPriv_.var.cmd.idx == (8U * 4U)) {
l_rx.var.cmd.idx = 0U; QS_rxPriv_.var.cmd.idx = 0U;
QS_RX_TRAN_(WAIT4_CMD_PARAM3); QS_RX_TRAN_(WAIT4_CMD_PARAM3);
} }
break; break;
} }
case (uint8_t)WAIT4_CMD_PARAM3: { case (uint8_t)WAIT4_CMD_PARAM3: {
l_rx.var.cmd.param3 |= ((uint32_t)b << l_rx.var.cmd.idx); QS_rxPriv_.var.cmd.param3 |= ((uint32_t)b << QS_rxPriv_.var.cmd.idx);
l_rx.var.cmd.idx += 8U; QS_rxPriv_.var.cmd.idx += 8U;
if (l_rx.var.cmd.idx == (8U * 4U)) { if (QS_rxPriv_.var.cmd.idx == (8U * 4U)) {
l_rx.var.cmd.idx = 0U; QS_rxPriv_.var.cmd.idx = 0U;
QS_RX_TRAN_(WAIT4_CMD_FRAME); QS_RX_TRAN_(WAIT4_CMD_FRAME);
} }
break; break;
@ -488,7 +405,7 @@ static void QS_rxParseData_(uint8_t const b) {
break; break;
} }
case (uint8_t)WAIT4_TICK_RATE: { case (uint8_t)WAIT4_TICK_RATE: {
l_rx.var.tick.rate = (uint_fast8_t)b; QS_rxPriv_.var.tick.rate = (uint_fast8_t)b;
QS_RX_TRAN_(WAIT4_TICK_FRAME); QS_RX_TRAN_(WAIT4_TICK_FRAME);
break; break;
} }
@ -497,19 +414,19 @@ static void QS_rxParseData_(uint8_t const b) {
break; break;
} }
case (uint8_t)WAIT4_PEEK_OFFS: { case (uint8_t)WAIT4_PEEK_OFFS: {
if (l_rx.var.peek.idx == 0U) { if (QS_rxPriv_.var.peek.idx == 0U) {
l_rx.var.peek.offs = (uint16_t)b; QS_rxPriv_.var.peek.offs = (uint16_t)b;
l_rx.var.peek.idx += 8U; QS_rxPriv_.var.peek.idx += 8U;
} }
else { else {
l_rx.var.peek.offs |= (uint16_t)((uint16_t)b << 8U); QS_rxPriv_.var.peek.offs |= (uint16_t)((uint16_t)b << 8U);
QS_RX_TRAN_(WAIT4_PEEK_SIZE); QS_RX_TRAN_(WAIT4_PEEK_SIZE);
} }
break; break;
} }
case (uint8_t)WAIT4_PEEK_SIZE: { case (uint8_t)WAIT4_PEEK_SIZE: {
if ((b == 1U) || (b == 2U) || (b == 4U)) { if ((b == 1U) || (b == 2U) || (b == 4U)) {
l_rx.var.peek.size = b; QS_rxPriv_.var.peek.size = b;
QS_RX_TRAN_(WAIT4_PEEK_NUM); QS_RX_TRAN_(WAIT4_PEEK_NUM);
} }
else { else {
@ -519,7 +436,7 @@ static void QS_rxParseData_(uint8_t const b) {
break; break;
} }
case (uint8_t)WAIT4_PEEK_NUM: { case (uint8_t)WAIT4_PEEK_NUM: {
l_rx.var.peek.num = b; QS_rxPriv_.var.peek.num = b;
QS_RX_TRAN_(WAIT4_PEEK_FRAME); QS_RX_TRAN_(WAIT4_PEEK_FRAME);
break; break;
} }
@ -528,23 +445,23 @@ static void QS_rxParseData_(uint8_t const b) {
break; break;
} }
case (uint8_t)WAIT4_POKE_OFFS: { case (uint8_t)WAIT4_POKE_OFFS: {
if (l_rx.var.poke.idx == 0U) { if (QS_rxPriv_.var.poke.idx == 0U) {
l_rx.var.poke.offs = (uint16_t)b; QS_rxPriv_.var.poke.offs = (uint16_t)b;
l_rx.var.poke.idx = 1U; QS_rxPriv_.var.poke.idx = 1U;
} }
else { else {
l_rx.var.poke.offs |= (uint16_t)((uint16_t)b << 8U); QS_rxPriv_.var.poke.offs |= (uint16_t)((uint16_t)b << 8U);
QS_RX_TRAN_(WAIT4_POKE_SIZE); QS_RX_TRAN_(WAIT4_POKE_SIZE);
} }
break; break;
} }
case (uint8_t)WAIT4_POKE_SIZE: { case (uint8_t)WAIT4_POKE_SIZE: {
if ((b == 1U) || (b == 2U) || (b == 4U)) { if ((b == 1U) || (b == 2U) || (b == 4U)) {
l_rx.var.poke.size = b; QS_rxPriv_.var.poke.size = b;
QS_RX_TRAN_(WAIT4_POKE_NUM); QS_RX_TRAN_(WAIT4_POKE_NUM);
} }
else { else {
QS_rxReportError_((l_rx.var.poke.fill != 0U) QS_rxReportError_((QS_rxPriv_.var.poke.fill != 0U)
? (int8_t)QS_RX_FILL ? (int8_t)QS_RX_FILL
: (int8_t)QS_RX_POKE); : (int8_t)QS_RX_POKE);
QS_RX_TRAN_(ERROR_STATE); QS_RX_TRAN_(ERROR_STATE);
@ -553,15 +470,15 @@ static void QS_rxParseData_(uint8_t const b) {
} }
case (uint8_t)WAIT4_POKE_NUM: { case (uint8_t)WAIT4_POKE_NUM: {
if (b > 0U) { if (b > 0U) {
l_rx.var.poke.num = b; QS_rxPriv_.var.poke.num = b;
l_rx.var.poke.data = 0U; QS_rxPriv_.var.poke.data = 0U;
l_rx.var.poke.idx = 0U; QS_rxPriv_.var.poke.idx = 0U;
QS_RX_TRAN_((l_rx.var.poke.fill != 0U) QS_RX_TRAN_((QS_rxPriv_.var.poke.fill != 0U)
? WAIT4_FILL_DATA ? WAIT4_FILL_DATA
: WAIT4_POKE_DATA); : WAIT4_POKE_DATA);
} }
else { else {
QS_rxReportError_((l_rx.var.poke.fill != 0U) QS_rxReportError_((QS_rxPriv_.var.poke.fill != 0U)
? (int8_t)QS_RX_FILL ? (int8_t)QS_RX_FILL
: (int8_t)QS_RX_POKE); : (int8_t)QS_RX_POKE);
QS_RX_TRAN_(ERROR_STATE); QS_RX_TRAN_(ERROR_STATE);
@ -569,20 +486,20 @@ static void QS_rxParseData_(uint8_t const b) {
break; break;
} }
case (uint8_t)WAIT4_FILL_DATA: { case (uint8_t)WAIT4_FILL_DATA: {
l_rx.var.poke.data |= ((uint32_t)b << l_rx.var.poke.idx); QS_rxPriv_.var.poke.data |= ((uint32_t)b << QS_rxPriv_.var.poke.idx);
l_rx.var.poke.idx += 8U; QS_rxPriv_.var.poke.idx += 8U;
if ((uint8_t)(l_rx.var.poke.idx >> 3U) == l_rx.var.poke.size) { if ((uint8_t)(QS_rxPriv_.var.poke.idx >> 3U) == QS_rxPriv_.var.poke.size) {
QS_RX_TRAN_(WAIT4_FILL_FRAME); QS_RX_TRAN_(WAIT4_FILL_FRAME);
} }
break; break;
} }
case (uint8_t)WAIT4_POKE_DATA: { case (uint8_t)WAIT4_POKE_DATA: {
l_rx.var.poke.data |= ((uint32_t)b << l_rx.var.poke.idx); QS_rxPriv_.var.poke.data |= ((uint32_t)b << QS_rxPriv_.var.poke.idx);
l_rx.var.poke.idx += 8U; QS_rxPriv_.var.poke.idx += 8U;
if ((uint8_t)(l_rx.var.poke.idx >> 3U) == l_rx.var.poke.size) { if ((uint8_t)(QS_rxPriv_.var.poke.idx >> 3U) == QS_rxPriv_.var.poke.size) {
QS_rxPoke_(); QS_rxPoke_();
--l_rx.var.poke.num; --QS_rxPriv_.var.poke.num;
if (l_rx.var.poke.num == 0U) { if (QS_rxPriv_.var.poke.num == 0U) {
QS_RX_TRAN_(WAIT4_POKE_FRAME); QS_RX_TRAN_(WAIT4_POKE_FRAME);
} }
} }
@ -597,20 +514,20 @@ static void QS_rxParseData_(uint8_t const b) {
break; break;
} }
case (uint8_t)WAIT4_FILTER_LEN: { case (uint8_t)WAIT4_FILTER_LEN: {
if (b == sizeof(l_rx.var.flt.data)) { if (b == sizeof(QS_rxPriv_.var.flt.data)) {
l_rx.var.flt.idx = 0U; QS_rxPriv_.var.flt.idx = 0U;
QS_RX_TRAN_(WAIT4_FILTER_DATA); QS_RX_TRAN_(WAIT4_FILTER_DATA);
} }
else { else {
QS_rxReportError_(l_rx.var.flt.recId); QS_rxReportError_(QS_rxPriv_.var.flt.recId);
QS_RX_TRAN_(ERROR_STATE); QS_RX_TRAN_(ERROR_STATE);
} }
break; break;
} }
case (uint8_t)WAIT4_FILTER_DATA: { case (uint8_t)WAIT4_FILTER_DATA: {
l_rx.var.flt.data[l_rx.var.flt.idx] = b; QS_rxPriv_.var.flt.data[QS_rxPriv_.var.flt.idx] = b;
++l_rx.var.flt.idx; ++QS_rxPriv_.var.flt.idx;
if (l_rx.var.flt.idx == sizeof(l_rx.var.flt.data)) { if (QS_rxPriv_.var.flt.idx == sizeof(QS_rxPriv_.var.flt.data)) {
QS_RX_TRAN_(WAIT4_FILTER_FRAME); QS_RX_TRAN_(WAIT4_FILTER_FRAME);
} }
break; break;
@ -621,21 +538,21 @@ static void QS_rxParseData_(uint8_t const b) {
} }
case (uint8_t)WAIT4_OBJ_KIND: { case (uint8_t)WAIT4_OBJ_KIND: {
if (b <= (uint8_t)SM_AO_OBJ) { if (b <= (uint8_t)SM_AO_OBJ) {
l_rx.var.obj.kind = b; QS_rxPriv_.var.obj.kind = b;
l_rx.var.obj.addr = 0U; QS_rxPriv_.var.obj.addr = 0U;
l_rx.var.obj.idx = 0U; QS_rxPriv_.var.obj.idx = 0U;
QS_RX_TRAN_(WAIT4_OBJ_ADDR); QS_RX_TRAN_(WAIT4_OBJ_ADDR);
} }
else { else {
QS_rxReportError_(l_rx.var.obj.recId); QS_rxReportError_(QS_rxPriv_.var.obj.recId);
QS_RX_TRAN_(ERROR_STATE); QS_RX_TRAN_(ERROR_STATE);
} }
break; break;
} }
case (uint8_t)WAIT4_OBJ_ADDR: { case (uint8_t)WAIT4_OBJ_ADDR: {
l_rx.var.obj.addr |= ((QSObj)b << l_rx.var.obj.idx); QS_rxPriv_.var.obj.addr |= ((QSObj)b << QS_rxPriv_.var.obj.idx);
l_rx.var.obj.idx += 8U; QS_rxPriv_.var.obj.idx += 8U;
if (l_rx.var.obj.idx == (uint8_t)(8U * QS_OBJ_PTR_SIZE)) { if (QS_rxPriv_.var.obj.idx == (uint8_t)(8U * QS_OBJ_PTR_SIZE)) {
QS_RX_TRAN_(WAIT4_OBJ_FRAME); QS_RX_TRAN_(WAIT4_OBJ_FRAME);
} }
break; break;
@ -646,11 +563,11 @@ static void QS_rxParseData_(uint8_t const b) {
} }
case (uint8_t)WAIT4_QUERY_KIND: { case (uint8_t)WAIT4_QUERY_KIND: {
if (b < (uint8_t)MAX_OBJ) { if (b < (uint8_t)MAX_OBJ) {
l_rx.var.obj.kind = b; QS_rxPriv_.var.obj.kind = b;
QS_RX_TRAN_(WAIT4_QUERY_FRAME); QS_RX_TRAN_(WAIT4_QUERY_FRAME);
} }
else { else {
QS_rxReportError_(l_rx.var.obj.recId); QS_rxReportError_(QS_rxPriv_.var.obj.recId);
QS_RX_TRAN_(ERROR_STATE); QS_RX_TRAN_(ERROR_STATE);
} }
break; break;
@ -660,40 +577,40 @@ static void QS_rxParseData_(uint8_t const b) {
break; break;
} }
case (uint8_t)WAIT4_EVT_PRIO: { case (uint8_t)WAIT4_EVT_PRIO: {
l_rx.var.evt.prio = b; QS_rxPriv_.var.evt.prio = b;
l_rx.var.evt.sig = 0U; QS_rxPriv_.var.evt.sig = 0U;
l_rx.var.evt.idx = 0U; QS_rxPriv_.var.evt.idx = 0U;
QS_RX_TRAN_(WAIT4_EVT_SIG); QS_RX_TRAN_(WAIT4_EVT_SIG);
break; break;
} }
case (uint8_t)WAIT4_EVT_SIG: { case (uint8_t)WAIT4_EVT_SIG: {
l_rx.var.evt.sig |= (QSignal)((uint32_t)b << l_rx.var.evt.idx); QS_rxPriv_.var.evt.sig |= (QSignal)((uint32_t)b << QS_rxPriv_.var.evt.idx);
l_rx.var.evt.idx += 8U; QS_rxPriv_.var.evt.idx += 8U;
if (l_rx.var.evt.idx == (uint8_t)(8U * Q_SIGNAL_SIZE)) { if (QS_rxPriv_.var.evt.idx == (uint8_t)(8U * Q_SIGNAL_SIZE)) {
l_rx.var.evt.len = 0U; QS_rxPriv_.var.evt.len = 0U;
l_rx.var.evt.idx = 0U; QS_rxPriv_.var.evt.idx = 0U;
QS_RX_TRAN_(WAIT4_EVT_LEN); QS_RX_TRAN_(WAIT4_EVT_LEN);
} }
break; break;
} }
case (uint8_t)WAIT4_EVT_LEN: { case (uint8_t)WAIT4_EVT_LEN: {
l_rx.var.evt.len |= (uint16_t)((uint32_t)b << l_rx.var.evt.idx); QS_rxPriv_.var.evt.len |= (uint16_t)((uint32_t)b << QS_rxPriv_.var.evt.idx);
l_rx.var.evt.idx += 8U; QS_rxPriv_.var.evt.idx += 8U;
if (l_rx.var.evt.idx == (8U * 2U)) { if (QS_rxPriv_.var.evt.idx == (8U * 2U)) {
if ((l_rx.var.evt.len + sizeof(QEvt)) <= if ((QS_rxPriv_.var.evt.len + sizeof(QEvt))
QF_poolGetMaxBlockSize()) <= QF_poolGetMaxBlockSize())
{ {
// report Ack before generating any other QS records // report Ack before generating any other QS records
QS_rxReportAck_((int8_t)QS_RX_EVENT); QS_rxReportAck_((int8_t)QS_RX_EVENT);
l_rx.var.evt.e = QF_newX_( QS_rxPriv_.var.evt.e = QF_newX_(
((uint_fast16_t)l_rx.var.evt.len + sizeof(QEvt)), ((uint_fast16_t)QS_rxPriv_.var.evt.len + sizeof(QEvt)),
0U, // margin 0U, // margin
(enum_t)l_rx.var.evt.sig); (enum_t)QS_rxPriv_.var.evt.sig);
if (l_rx.var.evt.e != (QEvt *)0) { // evt allocated? if (QS_rxPriv_.var.evt.e != (QEvt *)0) { // evt allocated?
l_rx.var.evt.p = (uint8_t *)l_rx.var.evt.e; QS_rxPriv_.var.evt.p = (uint8_t *)QS_rxPriv_.var.evt.e;
l_rx.var.evt.p = &l_rx.var.evt.p[sizeof(QEvt)]; QS_rxPriv_.var.evt.p = &QS_rxPriv_.var.evt.p[sizeof(QEvt)];
if (l_rx.var.evt.len > 0U) { if (QS_rxPriv_.var.evt.len > 0U) {
QS_RX_TRAN_(WAIT4_EVT_PAR); QS_RX_TRAN_(WAIT4_EVT_PAR);
} }
else { else {
@ -713,10 +630,10 @@ static void QS_rxParseData_(uint8_t const b) {
break; break;
} }
case (uint8_t)WAIT4_EVT_PAR: { // event parameters case (uint8_t)WAIT4_EVT_PAR: { // event parameters
*l_rx.var.evt.p = b; *QS_rxPriv_.var.evt.p = b;
++l_rx.var.evt.p; ++QS_rxPriv_.var.evt.p;
--l_rx.var.evt.len; --QS_rxPriv_.var.evt.len;
if (l_rx.var.evt.len == 0U) { if (QS_rxPriv_.var.evt.len == 0U) {
QS_RX_TRAN_(WAIT4_EVT_FRAME); QS_RX_TRAN_(WAIT4_EVT_FRAME);
} }
break; break;
@ -740,19 +657,19 @@ static void QS_rxParseData_(uint8_t const b) {
break; break;
} }
case (uint8_t)WAIT4_TEST_PROBE_DATA: { case (uint8_t)WAIT4_TEST_PROBE_DATA: {
l_rx.var.tp.data |= ((uint32_t)b << l_rx.var.tp.idx); QS_rxPriv_.var.tp.data |= ((uint32_t)b << QS_rxPriv_.var.tp.idx);
l_rx.var.tp.idx += 8U; QS_rxPriv_.var.tp.idx += 8U;
if (l_rx.var.tp.idx == (uint8_t)(8U * sizeof(uint32_t))) { if (QS_rxPriv_.var.tp.idx == (uint8_t)(8U * sizeof(uint32_t))) {
l_rx.var.tp.addr = 0U; QS_rxPriv_.var.tp.addr = 0U;
l_rx.var.tp.idx = 0U; QS_rxPriv_.var.tp.idx = 0U;
QS_RX_TRAN_(WAIT4_TEST_PROBE_ADDR); QS_RX_TRAN_(WAIT4_TEST_PROBE_ADDR);
} }
break; break;
} }
case (uint8_t)WAIT4_TEST_PROBE_ADDR: { case (uint8_t)WAIT4_TEST_PROBE_ADDR: {
l_rx.var.tp.addr |= ((QSFun)b << l_rx.var.tp.idx); QS_rxPriv_.var.tp.addr |= ((QSFun)b << QS_rxPriv_.var.tp.idx);
l_rx.var.tp.idx += 8U; QS_rxPriv_.var.tp.idx += 8U;
if (l_rx.var.tp.idx == (uint8_t)(8U * QS_FUN_PTR_SIZE)) { if (QS_rxPriv_.var.tp.idx == (uint8_t)(8U * QS_FUN_PTR_SIZE)) {
QS_RX_TRAN_(WAIT4_TEST_PROBE_FRAME); QS_RX_TRAN_(WAIT4_TEST_PROBE_FRAME);
} }
break; break;
@ -779,11 +696,16 @@ static void QS_rxParseData_(uint8_t const b) {
static void QS_rxHandleGoodFrame_(uint8_t const state) { static void QS_rxHandleGoodFrame_(uint8_t const state) {
uint8_t i; uint8_t i;
uint8_t *ptr; uint8_t *ptr;
QS_CRIT_STAT
switch (state) { switch (state) {
case WAIT4_INFO_FRAME: { case WAIT4_INFO_FRAME: {
// no need to report Ack or Done // no need to report Ack or Done
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_target_info_pre_(0U); // send only Target info QS_target_info_pre_(0U); // send only Target info
QS_MEM_APP();
QS_CRIT_EXIT();
break; break;
} }
case WAIT4_RESET_FRAME: { case WAIT4_RESET_FRAME: {
@ -796,8 +718,8 @@ static void QS_rxHandleGoodFrame_(uint8_t const state) {
case WAIT4_CMD_PARAM3: // intentionally fall-through case WAIT4_CMD_PARAM3: // intentionally fall-through
case WAIT4_CMD_FRAME: { case WAIT4_CMD_FRAME: {
QS_rxReportAck_((int8_t)QS_RX_COMMAND); QS_rxReportAck_((int8_t)QS_RX_COMMAND);
QS_onCommand(l_rx.var.cmd.cmdId, l_rx.var.cmd.param1, QS_onCommand(QS_rxPriv_.var.cmd.cmdId, QS_rxPriv_.var.cmd.param1,
l_rx.var.cmd.param2, l_rx.var.cmd.param3); QS_rxPriv_.var.cmd.param2, QS_rxPriv_.var.cmd.param3);
#ifdef Q_UTEST #ifdef Q_UTEST
#if Q_UTEST != 0 #if Q_UTEST != 0
QS_processTestEvts_(); // process all events produced QS_processTestEvts_(); // process all events produced
@ -809,27 +731,29 @@ static void QS_rxHandleGoodFrame_(uint8_t const state) {
case WAIT4_TICK_FRAME: { case WAIT4_TICK_FRAME: {
QS_rxReportAck_((int8_t)QS_RX_TICK); QS_rxReportAck_((int8_t)QS_RX_TICK);
#ifdef Q_UTEST #ifdef Q_UTEST
QTimeEvt_tick1_((uint_fast8_t)l_rx.var.tick.rate, &QS_rxPriv_); QTimeEvt_tick1_((uint_fast8_t)QS_rxPriv_.var.tick.rate, &QS_rxPriv_);
#if Q_UTEST != 0 #if Q_UTEST != 0
QS_processTestEvts_(); // process all events produced QS_processTestEvts_(); // process all events produced
#endif // Q_UTEST != 0 #endif // Q_UTEST != 0
#else #else
QTimeEvt_tick_((uint_fast8_t)l_rx.var.tick.rate, &QS_rxPriv_); QTimeEvt_tick_((uint_fast8_t)QS_rxPriv_.var.tick.rate, &QS_rxPriv_);
#endif // Q_UTEST #endif // Q_UTEST
QS_rxReportDone_((int8_t)QS_RX_TICK); QS_rxReportDone_((int8_t)QS_RX_TICK);
break; break;
} }
case WAIT4_PEEK_FRAME: { case WAIT4_PEEK_FRAME: {
// no need to report Ack or Done // no need to report Ack or Done
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_beginRec_((uint_fast8_t)QS_PEEK_DATA); QS_beginRec_((uint_fast8_t)QS_PEEK_DATA);
ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ]; ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ];
ptr = &ptr[l_rx.var.peek.offs]; ptr = &ptr[QS_rxPriv_.var.peek.offs];
QS_TIME_PRE_(); // timestamp QS_TIME_PRE_(); // timestamp
QS_U16_PRE_(l_rx.var.peek.offs); // data offset QS_U16_PRE_(QS_rxPriv_.var.peek.offs); // data offset
QS_U8_PRE_(l_rx.var.peek.size); // data size QS_U8_PRE_(QS_rxPriv_.var.peek.size); // data size
QS_U8_PRE_(l_rx.var.peek.num); // # data items QS_U8_PRE_(QS_rxPriv_.var.peek.num); // # data items
for (i = 0U; i < l_rx.var.peek.num; ++i) { for (i = 0U; i < QS_rxPriv_.var.peek.num; ++i) {
switch (l_rx.var.peek.size) { switch (QS_rxPriv_.var.peek.size) {
case 1: case 1:
QS_U8_PRE_(ptr[i]); QS_U8_PRE_(ptr[i]);
break; break;
@ -845,6 +769,8 @@ static void QS_rxHandleGoodFrame_(uint8_t const state) {
} }
} }
QS_endRec_(); QS_endRec_();
QS_MEM_APP();
QS_CRIT_EXIT();
QS_REC_DONE(); // user callback (if defined) QS_REC_DONE(); // user callback (if defined)
break; break;
@ -862,18 +788,18 @@ static void QS_rxHandleGoodFrame_(uint8_t const state) {
case WAIT4_FILL_FRAME: { case WAIT4_FILL_FRAME: {
QS_rxReportAck_((int8_t)QS_RX_FILL); QS_rxReportAck_((int8_t)QS_RX_FILL);
ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ]; ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ];
ptr = &ptr[l_rx.var.poke.offs]; ptr = &ptr[QS_rxPriv_.var.poke.offs];
for (i = 0U; i < l_rx.var.poke.num; ++i) { for (i = 0U; i < QS_rxPriv_.var.poke.num; ++i) {
switch (l_rx.var.poke.size) { switch (QS_rxPriv_.var.poke.size) {
case 1: case 1:
ptr[i] = (uint8_t)l_rx.var.poke.data; ptr[i] = (uint8_t)QS_rxPriv_.var.poke.data;
break; break;
case 2: case 2:
((uint16_t *)ptr)[i] ((uint16_t *)ptr)[i]
= (uint16_t)l_rx.var.poke.data; = (uint16_t)QS_rxPriv_.var.poke.data;
break; break;
case 4: case 4:
((uint32_t *)ptr)[i] = l_rx.var.poke.data; ((uint32_t *)ptr)[i] = QS_rxPriv_.var.poke.data;
break; break;
default: default:
// intentionally empty // intentionally empty
@ -883,12 +809,12 @@ static void QS_rxHandleGoodFrame_(uint8_t const state) {
break; break;
} }
case WAIT4_FILTER_FRAME: { case WAIT4_FILTER_FRAME: {
QS_rxReportAck_(l_rx.var.flt.recId); QS_rxReportAck_(QS_rxPriv_.var.flt.recId);
// apply the received filters // apply the received filters
if (l_rx.var.flt.recId == (int8_t)QS_RX_GLB_FILTER) { if (QS_rxPriv_.var.flt.recId == (int8_t)QS_RX_GLB_FILTER) {
for (i = 0U; i < Q_DIM(QS_filt_.glb); ++i) { for (i = 0U; i < Q_DIM(QS_filt_.glb); ++i) {
QS_filt_.glb[i] = l_rx.var.flt.data[i]; QS_filt_.glb[i] = QS_rxPriv_.var.flt.data[i];
} }
// leave the "not maskable" filters enabled, // leave the "not maskable" filters enabled,
// see qs.h, Miscellaneous QS records (not maskable) // see qs.h, Miscellaneous QS records (not maskable)
@ -899,33 +825,31 @@ static void QS_rxHandleGoodFrame_(uint8_t const state) {
// never enable the last 3 records (0x7D, 0x7E, 0x7F) // never enable the last 3 records (0x7D, 0x7E, 0x7F)
QS_filt_.glb[15] &= 0x1FU; QS_filt_.glb[15] &= 0x1FU;
} }
else if (l_rx.var.flt.recId == (int8_t)QS_RX_LOC_FILTER) { else if (QS_rxPriv_.var.flt.recId == (int8_t)QS_RX_LOC_FILTER) {
for (i = 0U; i < Q_DIM(QS_filt_.loc); ++i) { for (i = 0U; i < Q_DIM(QS_filt_.loc); ++i) {
QS_filt_.loc[i] = l_rx.var.flt.data[i]; QS_filt_.loc[i] = QS_rxPriv_.var.flt.data[i];
} }
// leave QS_ID == 0 always on // leave QS_ID == 0 always on
QS_filt_.loc[0] |= 0x01U; QS_filt_.loc[0] |= 0x01U;
} }
else { else {
QS_rxReportError_(l_rx.var.flt.recId); QS_rxReportError_(QS_rxPriv_.var.flt.recId);
} }
// no need to report Done // no need to report Done
break; break;
} }
case WAIT4_OBJ_FRAME: { case WAIT4_OBJ_FRAME: {
i = l_rx.var.obj.kind; i = QS_rxPriv_.var.obj.kind;
if (i < (uint8_t)MAX_OBJ) { if (i < (uint8_t)MAX_OBJ) {
if (l_rx.var.obj.recId == (int8_t)QS_RX_CURR_OBJ) { if (QS_rxPriv_.var.obj.recId == (int8_t)QS_RX_CURR_OBJ) {
QS_rxPriv_.currObj[i] = (void *)l_rx.var.obj.addr; QS_rxPriv_.currObj[i] = (void *)QS_rxPriv_.var.obj.addr;
QS_rxReportAck_((int8_t)QS_RX_CURR_OBJ); QS_rxReportAck_((int8_t)QS_RX_CURR_OBJ);
} }
else if (l_rx.var.obj.recId == (int8_t)QS_RX_AO_FILTER) { else if (QS_rxPriv_.var.obj.recId == (int8_t)QS_RX_AO_FILTER) {
if (l_rx.var.obj.addr != 0U) { if (QS_rxPriv_.var.obj.addr != 0U) {
int_fast16_t const filter = int_fast16_t const filter =
(int_fast16_t)((QActive *)l_rx.var.obj.addr)->prio; (int_fast16_t)((QActive *)QS_rxPriv_.var.obj.addr)->prio;
QS_locFilter_((i == 0U) QS_locFilter_((i == 0U) ? filter :-filter);
? filter
:-filter);
QS_rxReportAck_((int8_t)QS_RX_AO_FILTER); QS_rxReportAck_((int8_t)QS_RX_AO_FILTER);
} }
else { else {
@ -933,39 +857,39 @@ static void QS_rxHandleGoodFrame_(uint8_t const state) {
} }
} }
else { else {
QS_rxReportError_(l_rx.var.obj.recId); QS_rxReportError_(QS_rxPriv_.var.obj.recId);
} }
} }
// both SM and AO // both SM and AO
else if (i == (uint8_t)SM_AO_OBJ) { else if (i == (uint8_t)SM_AO_OBJ) {
if (l_rx.var.obj.recId == (int8_t)QS_RX_CURR_OBJ) { if (QS_rxPriv_.var.obj.recId == (int8_t)QS_RX_CURR_OBJ) {
QS_rxPriv_.currObj[SM_OBJ] = (void *)l_rx.var.obj.addr; QS_rxPriv_.currObj[SM_OBJ] = (void *)QS_rxPriv_.var.obj.addr;
QS_rxPriv_.currObj[AO_OBJ] = (void *)l_rx.var.obj.addr; QS_rxPriv_.currObj[AO_OBJ] = (void *)QS_rxPriv_.var.obj.addr;
} }
QS_rxReportAck_(l_rx.var.obj.recId); QS_rxReportAck_(QS_rxPriv_.var.obj.recId);
} }
else { else {
QS_rxReportError_(l_rx.var.obj.recId); QS_rxReportError_(QS_rxPriv_.var.obj.recId);
} }
break; break;
} }
case WAIT4_QUERY_FRAME: { case WAIT4_QUERY_FRAME: {
QS_queryCurrObj(l_rx.var.obj.kind); QS_queryCurrObj(QS_rxPriv_.var.obj.kind);
break; break;
} }
case WAIT4_EVT_FRAME: { case WAIT4_EVT_FRAME: {
// NOTE: Ack was already reported in the WAIT4_EVT_LEN state // NOTE: Ack was already reported in the WAIT4_EVT_LEN state
#ifdef Q_UTEST #ifdef Q_UTEST
QS_onTestEvt(l_rx.var.evt.e); // adjust the event, if needed QS_onTestEvt(QS_rxPriv_.var.evt.e); // adjust the event, if needed
#endif // Q_UTEST #endif // Q_UTEST
i = 0U; // use 'i' as status, 0 == success,no-recycle i = 0U; // use 'i' as status, 0 == success,no-recycle
if (l_rx.var.evt.prio == 0U) { // publish if (QS_rxPriv_.var.evt.prio == 0U) { // publish
QActive_publish_(l_rx.var.evt.e, &QS_rxPriv_, 0U); QActive_publish_(QS_rxPriv_.var.evt.e, &QS_rxPriv_, 0U);
} }
else if (l_rx.var.evt.prio < QF_MAX_ACTIVE) { else if (QS_rxPriv_.var.evt.prio < QF_MAX_ACTIVE) {
if (!QACTIVE_POST_X(QActive_registry_[l_rx.var.evt.prio], if (!QACTIVE_POST_X(QActive_registry_[QS_rxPriv_.var.evt.prio],
l_rx.var.evt.e, QS_rxPriv_.var.evt.e,
0U, // margin 0U, // margin
&QS_rxPriv_)) &QS_rxPriv_))
{ {
@ -973,44 +897,44 @@ static void QS_rxHandleGoodFrame_(uint8_t const state) {
i = 0x80U; // failure status, no recycle i = 0x80U; // failure status, no recycle
} }
} }
else if (l_rx.var.evt.prio == 255U) { // special prio else if (QS_rxPriv_.var.evt.prio == 255U) { // special prio
// dispatch to the current SM object // dispatch to the current SM object
if (QS_rxPriv_.currObj[SM_OBJ] != (void *)0) { if (QS_rxPriv_.currObj[SM_OBJ] != (void *)0) {
// increment the ref-ctr to simulate the situation // increment the ref-ctr to simulate the situation
// when the event is just retrieved from a queue. // when the event is just retrieved from a queue.
// This is expected for the following QF_gc() call. // This is expected for the following QF_gc() call.
++l_rx.var.evt.e->refCtr_; ++QS_rxPriv_.var.evt.e->refCtr_;
QAsm * const sm = (QAsm *)QS_rxPriv_.currObj[SM_OBJ]; QAsm * const sm = (QAsm *)QS_rxPriv_.currObj[SM_OBJ];
(*sm->vptr->dispatch)(sm, l_rx.var.evt.e, 0U); (*sm->vptr->dispatch)(sm, QS_rxPriv_.var.evt.e, 0U);
i = 0x01U; // success status, recycle needed i = 0x01U; // success status, recycle needed
} }
else { else {
i = 0x81U; // failure status, recycle needed i = 0x81U; // failure status, recycle needed
} }
} }
else if (l_rx.var.evt.prio == 254U) { // special prio else if (QS_rxPriv_.var.evt.prio == 254U) { // special prio
// init the current SM object" // init the current SM object"
if (QS_rxPriv_.currObj[SM_OBJ] != (void *)0) { if (QS_rxPriv_.currObj[SM_OBJ] != (void *)0) {
// increment the ref-ctr to simulate the situation // increment the ref-ctr to simulate the situation
// when the event is just retrieved from a queue. // when the event is just retrieved from a queue.
// This is expected for the following QF_gc() call. // This is expected for the following QF_gc() call.
++l_rx.var.evt.e->refCtr_; ++QS_rxPriv_.var.evt.e->refCtr_;
QAsm * const sm = (QAsm *)QS_rxPriv_.currObj[SM_OBJ]; QAsm * const sm = (QAsm *)QS_rxPriv_.currObj[SM_OBJ];
(*sm->vptr->init)(sm, l_rx.var.evt.e, 0U); (*sm->vptr->init)(sm, QS_rxPriv_.var.evt.e, 0U);
i = 0x01U; // success status, recycle needed i = 0x01U; // success status, recycle needed
} }
else { else {
i = 0x81U; // failure status, recycle needed i = 0x81U; // failure status, recycle needed
} }
} }
else if (l_rx.var.evt.prio == 253U) { // special prio else if (QS_rxPriv_.var.evt.prio == 253U) { // special prio
// post to the current AO // post to the current AO
if (QS_rxPriv_.currObj[AO_OBJ] != (void *)0) { if (QS_rxPriv_.currObj[AO_OBJ] != (void *)0) {
if (!QACTIVE_POST_X( if (!QACTIVE_POST_X(
(QActive *)QS_rxPriv_.currObj[AO_OBJ], (QActive *)QS_rxPriv_.currObj[AO_OBJ],
l_rx.var.evt.e, QS_rxPriv_.var.evt.e,
0U, // margin 0U, // margin
&QS_rxPriv_)) &QS_rxPriv_))
{ {
@ -1028,7 +952,7 @@ static void QS_rxHandleGoodFrame_(uint8_t const state) {
#if (QF_MAX_EPOOL > 0U) #if (QF_MAX_EPOOL > 0U)
if ((i & 0x01U) != 0U) { // recycle needed? if ((i & 0x01U) != 0U) { // recycle needed?
QF_gc(l_rx.var.evt.e); QF_gc(QS_rxPriv_.var.evt.e);
} }
#endif #endif
if ((i & 0x80U) != 0U) { // failure? if ((i & 0x80U) != 0U) { // failure?
@ -1048,8 +972,12 @@ static void QS_rxHandleGoodFrame_(uint8_t const state) {
#ifdef Q_UTEST #ifdef Q_UTEST
case WAIT4_TEST_SETUP_FRAME: { case WAIT4_TEST_SETUP_FRAME: {
QS_rxReportAck_((int8_t)QS_RX_TEST_SETUP); QS_rxReportAck_((int8_t)QS_RX_TEST_SETUP);
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_tstPriv_.tpNum = 0U; // clear the Test-Probes QS_tstPriv_.tpNum = 0U; // clear the Test-Probes
QS_tstPriv_.testTime = 0U; // clear the time tick QS_tstPriv_.testTime = 0U; // clear the time tick
QS_MEM_APP();
QS_CRIT_EXIT();
// don't clear current objects // don't clear current objects
QS_onTestSetup(); // application-specific test setup QS_onTestSetup(); // application-specific test setup
// no need to report Done // no need to report Done
@ -1069,10 +997,14 @@ static void QS_rxHandleGoodFrame_(uint8_t const state) {
} }
case WAIT4_TEST_PROBE_FRAME: { case WAIT4_TEST_PROBE_FRAME: {
QS_rxReportAck_((int8_t)QS_RX_TEST_PROBE); QS_rxReportAck_((int8_t)QS_RX_TEST_PROBE);
QS_CRIT_ENTRY();
QS_MEM_SYS();
Q_ASSERT_INCRIT(815, QS_tstPriv_.tpNum Q_ASSERT_INCRIT(815, QS_tstPriv_.tpNum
< (sizeof(QS_tstPriv_.tpBuf) / sizeof(QS_tstPriv_.tpBuf[0]))); < (sizeof(QS_tstPriv_.tpBuf) / sizeof(QS_tstPriv_.tpBuf[0])));
QS_tstPriv_.tpBuf[QS_tstPriv_.tpNum] = l_rx.var.tp; QS_tstPriv_.tpBuf[QS_tstPriv_.tpNum] = QS_rxPriv_.var.tp;
++QS_tstPriv_.tpNum; ++QS_tstPriv_.tpNum;
QS_MEM_APP();
QS_CRIT_EXIT();
// no need to report Done // no need to report Done
break; break;
} }
@ -1092,11 +1024,15 @@ static void QS_rxHandleGoodFrame_(uint8_t const state) {
//............................................................................ //............................................................................
static void QS_rxHandleBadFrame_(uint8_t const state) { static void QS_rxHandleBadFrame_(uint8_t const state) {
QS_rxReportError_(0x50); // report error for all bad frames QS_rxReportError_(0x50); // report error for all bad frames
switch (state) { switch (state) {
case WAIT4_EVT_FRAME: { case WAIT4_EVT_FRAME: {
Q_ASSERT_INCRIT(910, l_rx.var.evt.e != (QEvt *)0); QS_CRIT_STAT
QS_CRIT_ENTRY();
Q_ASSERT_INCRIT(910, QS_rxPriv_.var.evt.e != (QEvt *)0);
QS_CRIT_EXIT();
#if (QF_MAX_EPOOL > 0U) #if (QF_MAX_EPOOL > 0U)
QF_gc(l_rx.var.evt.e); // don't leak an allocated event QF_gc(QS_rxPriv_.var.evt.e); // don't leak allocated evt
#endif #endif
break; break;
} }
@ -1109,32 +1045,54 @@ static void QS_rxHandleBadFrame_(uint8_t const state) {
//............................................................................ //............................................................................
static void QS_rxReportAck_(int8_t const recId) { static void QS_rxReportAck_(int8_t const recId) {
QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_beginRec_((uint_fast8_t)QS_RX_STATUS); QS_beginRec_((uint_fast8_t)QS_RX_STATUS);
QS_U8_PRE_(recId); // record ID QS_U8_PRE_(recId); // record ID
QS_endRec_(); QS_endRec_();
QS_MEM_APP();
QS_CRIT_EXIT();
QS_REC_DONE(); // user callback (if defined) QS_REC_DONE(); // user callback (if defined)
} }
//............................................................................ //............................................................................
static void QS_rxReportError_(int8_t const code) { static void QS_rxReportError_(int8_t const code) {
QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_beginRec_((uint_fast8_t)QS_RX_STATUS); QS_beginRec_((uint_fast8_t)QS_RX_STATUS);
QS_U8_PRE_(0x80U | (uint8_t)code); // error code QS_U8_PRE_(0x80U | (uint8_t)code); // error code
QS_endRec_(); QS_endRec_();
QS_MEM_APP();
QS_CRIT_EXIT();
QS_REC_DONE(); // user callback (if defined) QS_REC_DONE(); // user callback (if defined)
} }
//............................................................................ //............................................................................
static void QS_rxReportDone_(int8_t const recId) { static void QS_rxReportDone_(int8_t const recId) {
QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_beginRec_((uint_fast8_t)QS_TARGET_DONE); QS_beginRec_((uint_fast8_t)QS_TARGET_DONE);
QS_TIME_PRE_(); // timestamp QS_TIME_PRE_(); // timestamp
QS_U8_PRE_(recId); // record ID QS_U8_PRE_(recId); // record ID
QS_endRec_(); QS_endRec_();
QS_MEM_APP();
QS_CRIT_EXIT();
QS_REC_DONE(); // user callback (if defined) QS_REC_DONE(); // user callback (if defined)
} }
//............................................................................ //............................................................................
static void QS_queryCurrObj(uint8_t const obj_kind) { static void QS_queryCurrObj(uint8_t const obj_kind) {
QS_CRIT_STAT
QS_CRIT_ENTRY();
Q_REQUIRE_INCRIT(800, obj_kind < Q_DIM(QS_rxPriv_.currObj));
QS_CRIT_EXIT();
if (QS_rxPriv_.currObj[obj_kind] != (void *)0) { if (QS_rxPriv_.currObj[obj_kind] != (void *)0) {
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_beginRec_((uint_fast8_t)QS_QUERY_DATA); QS_beginRec_((uint_fast8_t)QS_QUERY_DATA);
QS_TIME_PRE_(); // timestamp QS_TIME_PRE_(); // timestamp
QS_U8_PRE_(obj_kind); // object kind QS_U8_PRE_(obj_kind); // object kind
@ -1175,6 +1133,8 @@ static void QS_queryCurrObj(uint8_t const obj_kind) {
break; break;
} }
QS_endRec_(); QS_endRec_();
QS_MEM_APP();
QS_CRIT_EXIT();
QS_REC_DONE(); // user callback (if defined) QS_REC_DONE(); // user callback (if defined)
} }
else { else {
@ -1185,16 +1145,16 @@ static void QS_queryCurrObj(uint8_t const obj_kind) {
//............................................................................ //............................................................................
static void QS_rxPoke_(void) { static void QS_rxPoke_(void) {
uint8_t *ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ]; uint8_t *ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ];
ptr = &ptr[l_rx.var.poke.offs]; ptr = &ptr[QS_rxPriv_.var.poke.offs];
switch (l_rx.var.poke.size) { switch (QS_rxPriv_.var.poke.size) {
case 1: case 1:
*ptr = (uint8_t)l_rx.var.poke.data; *ptr = (uint8_t)QS_rxPriv_.var.poke.data;
break; break;
case 2: case 2:
*(uint16_t *)ptr = (uint16_t)l_rx.var.poke.data; *(uint16_t *)ptr = (uint16_t)QS_rxPriv_.var.poke.data;
break; break;
case 4: case 4:
*(uint32_t *)ptr = l_rx.var.poke.data; *(uint32_t *)ptr = QS_rxPriv_.var.poke.data;
break; break;
default: { default: {
Q_ERROR_INCRIT(900); Q_ERROR_INCRIT(900);
@ -1202,9 +1162,9 @@ static void QS_rxPoke_(void) {
} }
} }
l_rx.var.poke.data = 0U; QS_rxPriv_.var.poke.data = 0U;
l_rx.var.poke.idx = 0U; QS_rxPriv_.var.poke.idx = 0U;
l_rx.var.poke.offs += (uint16_t)l_rx.var.poke.size; QS_rxPriv_.var.poke.offs += (uint16_t)QS_rxPriv_.var.poke.size;
} }
//! @endcond //! @endcond