mirror of
https://github.com/QuantumLeaps/qpcpp.git
synced 2025-01-28 06:02:56 +08:00
1059 lines
37 KiB
C++
1059 lines
37 KiB
C++
//$file${include::qs.hpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
|
//
|
|
// Model: qpcpp.qm
|
|
// File: ${include::qs.hpp}
|
|
//
|
|
// This code has been generated by QM 6.2.0 <www.state-machine.com/qm>.
|
|
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
|
|
//
|
|
// This code is covered by the following QP license:
|
|
// License # : LicenseRef-QL-dual
|
|
// Issued to : Any user of the QP/C++ real-time embedded framework
|
|
// Framework(s) : qpcpp
|
|
// Support ends : 2025-12-31
|
|
// License scope:
|
|
//
|
|
// Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
|
|
//
|
|
// Q u a n t u m L e a P s
|
|
// ------------------------
|
|
// Modern Embedded Software
|
|
//
|
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
|
//
|
|
// This software is dual-licensed under the terms of the open source GNU
|
|
// General Public License version 3 (or any later version), or alternatively,
|
|
// under the terms of one of the closed source Quantum Leaps commercial
|
|
// licenses.
|
|
//
|
|
// The terms of the open source GNU General Public License version 3
|
|
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
|
//
|
|
// The terms of the closed source Quantum Leaps commercial licenses
|
|
// can be found at: <www.state-machine.com/licensing>
|
|
//
|
|
// Redistributions in source code must retain this top-level comment block.
|
|
// Plagiarizing this software to sidestep the license obligations is illegal.
|
|
//
|
|
// Contact information:
|
|
// <www.state-machine.com/licensing>
|
|
// <info@state-machine.com>
|
|
//
|
|
//$endhead${include::qs.hpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
#ifndef QS_HPP_
|
|
#define QS_HPP_
|
|
|
|
#ifndef Q_SPY
|
|
#error "Q_SPY must be defined to include qs.hpp"
|
|
#endif
|
|
|
|
//============================================================================
|
|
//! @cond INTERNAL
|
|
|
|
#ifndef QS_CTR_SIZE
|
|
#define QS_CTR_SIZE 2U
|
|
#endif
|
|
|
|
#ifndef QS_TIME_SIZE
|
|
#define QS_TIME_SIZE 4U
|
|
#endif
|
|
|
|
//! @endcond
|
|
//============================================================================
|
|
|
|
//$declare${QS::types} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
|
namespace QP {
|
|
|
|
//${QS::types::QSpyPre} ......................................................
|
|
//! pre-defined QS record IDs
|
|
enum QSpyPre : std::int8_t {
|
|
// [0] QS session (not maskable)
|
|
QS_EMPTY, //!< QS record for cleanly starting a session
|
|
|
|
// [1] SM records
|
|
QS_QEP_STATE_ENTRY, //!< a state was entered
|
|
QS_QEP_STATE_EXIT, //!< a state was exited
|
|
QS_QEP_STATE_INIT, //!< an initial transition was taken in a state
|
|
QS_QEP_INIT_TRAN, //!< the top-most initial transition was taken
|
|
QS_QEP_INTERN_TRAN, //!< an internal transition was taken
|
|
QS_QEP_TRAN, //!< a regular transition was taken
|
|
QS_QEP_IGNORED, //!< an event was ignored (silently discarded)
|
|
QS_QEP_DISPATCH, //!< an event was dispatched (begin of RTC step)
|
|
QS_QEP_UNHANDLED, //!< an event was un-handled due to a guard
|
|
|
|
// [10] Active Object (AO) records
|
|
QS_QF_ACTIVE_DEFER, //!< AO deferred an event
|
|
QS_QF_ACTIVE_RECALL, //!< AO recalled an event
|
|
QS_QF_ACTIVE_SUBSCRIBE, //!< an AO subscribed to an event
|
|
QS_QF_ACTIVE_UNSUBSCRIBE, //!< an AO unsubscribed to an event
|
|
QS_QF_ACTIVE_POST, //!< an event was posted (FIFO) directly to AO
|
|
QS_QF_ACTIVE_POST_LIFO, //!< an event was posted (LIFO) directly to AO
|
|
QS_QF_ACTIVE_GET, //!< AO got an event and its queue is not empty
|
|
QS_QF_ACTIVE_GET_LAST,//!< AO got an event and its queue is empty
|
|
QS_QF_ACTIVE_RECALL_ATTEMPT, //!< AO attempted to recall an event
|
|
|
|
// [19] Event Queue (EQ) records
|
|
QS_QF_EQUEUE_POST, //!< an event was posted (FIFO) to a raw queue
|
|
QS_QF_EQUEUE_POST_LIFO, //!< an event was posted (LIFO) to a raw queue
|
|
QS_QF_EQUEUE_GET, //!< get an event and queue still not empty
|
|
QS_QF_EQUEUE_GET_LAST,//!< get the last event from the queue
|
|
|
|
// [23] Framework (QF) records
|
|
QS_QF_NEW_ATTEMPT, //!< an attempt to allocate an event failed
|
|
|
|
// [24] Memory Pool (MP) records
|
|
QS_QF_MPOOL_GET, //!< a memory block was removed from memory pool
|
|
QS_QF_MPOOL_PUT, //!< a memory block was returned to memory pool
|
|
|
|
// [26] Additional Framework (QF) records
|
|
QS_QF_PUBLISH, //!< an event was published to active objects
|
|
QS_QF_NEW_REF, //!< new event reference was created
|
|
QS_QF_NEW, //!< new event was created
|
|
QS_QF_GC_ATTEMPT, //!< garbage collection attempt
|
|
QS_QF_GC, //!< garbage collection
|
|
QS_QF_TICK, //!< QTimeEvt tick was called
|
|
|
|
// [32] Time Event (TE) records
|
|
QS_QF_TIMEEVT_ARM, //!< a time event was armed
|
|
QS_QF_TIMEEVT_AUTO_DISARM, //!< a time event expired and was disarmed
|
|
QS_QF_TIMEEVT_DISARM_ATTEMPT,//!< attempt to disarm a disarmed QTimeEvt
|
|
QS_QF_TIMEEVT_DISARM, //!< true disarming of an armed time event
|
|
QS_QF_TIMEEVT_REARM, //!< rearming of a time event
|
|
QS_QF_TIMEEVT_POST, //!< a time event posted itself directly to an AO
|
|
|
|
// [38] Additional Framework (QF) records
|
|
QS_QF_DELETE_REF, //!< an event reference is about to be deleted
|
|
QS_QF_CRIT_ENTRY, //!< critical section was entered
|
|
QS_QF_CRIT_EXIT, //!< critical section was exited
|
|
QS_QF_ISR_ENTRY, //!< an ISR was entered
|
|
QS_QF_ISR_EXIT, //!< an ISR was exited
|
|
QS_QF_INT_DISABLE, //!< interrupts were disabled
|
|
QS_QF_INT_ENABLE, //!< interrupts were enabled
|
|
|
|
// [45] Additional Active Object (AO) records
|
|
QS_QF_ACTIVE_POST_ATTEMPT,//!< attempt to post an evt to AO failed
|
|
|
|
// [46] Additional Event Queue (EQ) records
|
|
QS_QF_EQUEUE_POST_ATTEMPT,//!< attempt to post evt to QEQueue failed
|
|
|
|
// [47] Additional Memory Pool (MP) records
|
|
QS_QF_MPOOL_GET_ATTEMPT, //!< attempt to get a memory block failed
|
|
|
|
// [48] Scheduler (SC) records
|
|
QS_SCHED_PREEMPT, //!< scheduler asynchronously preempted a task
|
|
QS_SCHED_RESTORE, //!< scheduler restored preempted task
|
|
QS_SCHED_LOCK, //!< scheduler was locked
|
|
QS_SCHED_UNLOCK, //!< scheduler was unlocked
|
|
QS_SCHED_NEXT, //!< scheduler started next task
|
|
QS_SCHED_IDLE, //!< scheduler restored the idle task
|
|
|
|
// [54] Miscellaneous QS records (not maskable)
|
|
QS_ENUM_DICT, //!< enumeration dictionary entry
|
|
|
|
// [55] Additional QEP records
|
|
QS_QEP_TRAN_HIST, //!< a tran. to history was taken
|
|
QS_QEP_TRAN_EP, //!< a tran. to entry point into a submachine
|
|
QS_QEP_TRAN_XP, //!< a tran. to exit point out of a submachine
|
|
|
|
// [58] Miscellaneous QS records (not maskable)
|
|
QS_TEST_PAUSED, //!< test has been paused
|
|
QS_TEST_PROBE_GET, //!< reports that Test-Probe has been used
|
|
QS_SIG_DICT, //!< signal dictionary entry
|
|
QS_OBJ_DICT, //!< object dictionary entry
|
|
QS_FUN_DICT, //!< function dictionary entry
|
|
QS_USR_DICT, //!< user QS record dictionary entry
|
|
QS_TARGET_INFO, //!< reports the Target information
|
|
QS_TARGET_DONE, //!< reports completion of a user callback
|
|
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
|
|
QS_ASSERT_FAIL, //!< assertion failed in the code
|
|
QS_QF_RUN, //!< QF_run() was entered
|
|
|
|
// [71] Semaphore (SEM) records
|
|
QS_SEM_TAKE, //!< a semaphore was taken by a thread
|
|
QS_SEM_BLOCK, //!< a semaphore blocked a thread
|
|
QS_SEM_SIGNAL, //!< a semaphore was signaled
|
|
QS_SEM_BLOCK_ATTEMPT, //!< a semaphore blocked was attempted
|
|
|
|
// [75] Mutex (MTX) records
|
|
QS_MTX_LOCK, //!< a mutex was locked
|
|
QS_MTX_BLOCK, //!< a mutex blocked a thread
|
|
QS_MTX_UNLOCK, //!< a mutex was unlocked
|
|
QS_MTX_LOCK_ATTEMPT, //!< a mutex lock was attempted
|
|
QS_MTX_BLOCK_ATTEMPT, //!< a mutex blocking was attempted
|
|
QS_MTX_UNLOCK_ATTEMPT,//!< a mutex unlock was attempted
|
|
|
|
// [81]
|
|
QS_PRE_MAX //!< the # predefined signals
|
|
};
|
|
|
|
//${QS::types::QSpyGroups} ...................................................
|
|
//! QS-TX record groups for QS_GLB_FILTER()
|
|
enum QSpyGroups : std::int16_t {
|
|
QS_ALL_RECORDS = 0xF0,//!< all maskable QS records
|
|
QS_SM_RECORDS, //!< State Machine QS records
|
|
QS_AO_RECORDS, //!< Active Object QS records
|
|
QS_EQ_RECORDS, //!< Event Queues QS records
|
|
QS_MP_RECORDS, //!< Memory Pools QS records
|
|
QS_TE_RECORDS, //!< Time Events QS records
|
|
QS_QF_RECORDS, //!< QF QS records
|
|
QS_SC_RECORDS, //!< Scheduler QS records
|
|
QS_SEM_RECORDS, //!< Semaphore QS records
|
|
QS_MTX_RECORDS, //!< Mutex QS records
|
|
QS_U0_RECORDS, //!< User Group 100-104 records
|
|
QS_U1_RECORDS, //!< User Group 105-109 records
|
|
QS_U2_RECORDS, //!< User Group 110-114 records
|
|
QS_U3_RECORDS, //!< User Group 115-119 records
|
|
QS_U4_RECORDS, //!< User Group 120-124 records
|
|
QS_UA_RECORDS //!< All User records
|
|
};
|
|
|
|
//${QS::types::QSpyUserOffsets} ..............................................
|
|
//! QS user record group offsets for QS_GLB_FILTER()
|
|
enum QSpyUserOffsets : std::int16_t {
|
|
QS_USER = 100, //!< the first record available to QS users
|
|
QS_USER0 = QS_USER, //!< offset for User Group 0
|
|
QS_USER1 = QS_USER0 + 5, //!< offset for User Group 1
|
|
QS_USER2 = QS_USER1 + 5, //!< offset for User Group 2
|
|
QS_USER3 = QS_USER2 + 5, //!< offset for User Group 3
|
|
QS_USER4 = QS_USER3 + 5 //!< offset for User Group 4
|
|
};
|
|
|
|
//${QS::types::QSpyIdOffsets} ................................................
|
|
//! QS ID offsets for QS_LOC_FILTER()
|
|
enum QSpyIdOffsets : std::int16_t {
|
|
QS_AO_ID = 0, //!< offset for AO priorities
|
|
QS_EP_ID = 64, //!< offset for event-pool IDs
|
|
QS_EQ_ID = 80, //!< offset for event-queue IDs
|
|
QS_AP_ID = 96 //!< offset for Application-specific IDs
|
|
};
|
|
|
|
//${QS::types::QSpyIdGroups} .................................................
|
|
//! QS ID groups for QS_LOC_FILTER()
|
|
enum QSpyIdGroups : std::int16_t {
|
|
QS_ALL_IDS = 0xF0, //!< all QS IDs
|
|
QS_AO_IDS = 0x80 + QS_AO_ID, //!< AO IDs (priorities)
|
|
QS_EP_IDS = 0x80 + QS_EP_ID, //!< event-pool IDs
|
|
QS_EQ_IDS = 0x80 + QS_EQ_ID, //!< event-queue IDs
|
|
QS_AP_IDS = 0x80 + QS_AP_ID //!< Application-specific IDs
|
|
};
|
|
|
|
//${QS::types::QSpyId} .......................................................
|
|
struct QSpyId {
|
|
std::uint8_t m_prio; //!< prio. (qsId) for the QS "local filter"
|
|
|
|
// get the prio. (qsId) from the QSpyId object
|
|
std::uint_fast8_t getPrio() const noexcept {
|
|
return static_cast<std::uint_fast8_t>(m_prio);
|
|
}
|
|
};
|
|
|
|
//${QS::types::QSObj} ........................................................
|
|
#if (QS_OBJ_PTR_SIZE == 2U)
|
|
using QSObj = std::uint16_t;
|
|
#endif // (QS_OBJ_PTR_SIZE == 2U)
|
|
|
|
//${QS::types::QSObj} ........................................................
|
|
#if (QS_OBJ_PTR_SIZE == 4U)
|
|
using QSObj = std::uint32_t;
|
|
#endif // (QS_OBJ_PTR_SIZE == 4U)
|
|
|
|
//${QS::types::QSObj} ........................................................
|
|
#if (QS_OBJ_PTR_SIZE == 8U)
|
|
using QSObj = std::uint64_t;
|
|
#endif // (QS_OBJ_PTR_SIZE == 8U)
|
|
|
|
//${QS::types::QSFun} ........................................................
|
|
#if (QS_FUN_PTR_SIZE == 2U)
|
|
using QSFun = std::uint16_t;
|
|
#endif // (QS_FUN_PTR_SIZE == 2U)
|
|
|
|
//${QS::types::QSFun} ........................................................
|
|
#if (QS_FUN_PTR_SIZE == 4U)
|
|
using QSFun = std::uint32_t;
|
|
#endif // (QS_FUN_PTR_SIZE == 4U)
|
|
|
|
//${QS::types::QSFun} ........................................................
|
|
#if (QS_FUN_PTR_SIZE == 8U)
|
|
using QSFun = std::uint64_t;
|
|
#endif // (QS_FUN_PTR_SIZE == 8U)
|
|
|
|
//${QS::types::QSpyFunPtr} ...................................................
|
|
using QSpyFunPtr = void (*)();
|
|
|
|
//${QS::types::QSCtr} ........................................................
|
|
#if (QS_CTR_SIZE == 2U)
|
|
using QSCtr = std::uint16_t;
|
|
#endif // (QS_CTR_SIZE == 2U)
|
|
|
|
//${QS::types::QSCtr} ........................................................
|
|
#if (QS_CTR_SIZE == 4U)
|
|
using QSCtr = std::uint32_t;
|
|
#endif // (QS_CTR_SIZE == 4U)
|
|
|
|
//${QS::types::QSTimeCtr} ....................................................
|
|
#if (QS_TIME_SIZE == 2U)
|
|
using QSTimeCtr = std::uint16_t;
|
|
#endif // (QS_TIME_SIZE == 2U)
|
|
|
|
//${QS::types::QSTimeCtr} ....................................................
|
|
#if (QS_TIME_SIZE == 4U)
|
|
using QSTimeCtr = std::uint32_t;
|
|
#endif // (QS_TIME_SIZE == 4U)
|
|
|
|
} // namespace QP
|
|
//$enddecl${QS::types} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
//$declare${QS::filters} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
|
namespace QP {
|
|
namespace QS {
|
|
|
|
//${QS::filters::Filter} .....................................................
|
|
class Filter {
|
|
public:
|
|
std::uint8_t glb[16];
|
|
std::uint8_t loc[16];
|
|
}; // class Filter
|
|
|
|
//${QS::filters::filt_} ......................................................
|
|
extern Filter filt_;
|
|
|
|
} // namespace QS
|
|
} // namespace QP
|
|
//$enddecl${QS::filters} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
//$declare${QS-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
|
|
|
//${QS-macros::QS_INIT} ......................................................
|
|
#define QS_INIT(arg_) (QP::QS::onStartup(arg_))
|
|
|
|
//${QS-macros::QS_EXIT} ......................................................
|
|
#define QS_EXIT() (QP::QS::onCleanup())
|
|
|
|
//${QS-macros::QS_OUTPUT} ....................................................
|
|
#define QS_OUTPUT() (QP::QS::doOutput())
|
|
|
|
//${QS-macros::QS_RX_INPUT} ..................................................
|
|
#define QS_RX_INPUT() (QP::QS::doInput())
|
|
|
|
//${QS-macros::QS_GLB_FILTER} ................................................
|
|
#define QS_GLB_FILTER(rec_) \
|
|
(QP::QS::glbFilter_(static_cast<std::int_fast16_t>(rec_)))
|
|
|
|
//${QS-macros::QS_LOC_FILTER} ................................................
|
|
#define QS_LOC_FILTER(qsId_) \
|
|
(QP::QS::locFilter_(static_cast<std::int_fast16_t>(qsId_)))
|
|
|
|
//${QS-macros::QS_BEGIN_ID} ..................................................
|
|
#define QS_BEGIN_ID(rec_, qsId_) \
|
|
if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qsId_)) { \
|
|
QS_CRIT_STAT \
|
|
QS_CRIT_ENTRY(); \
|
|
QS_MEM_SYS(); \
|
|
QP::QS::beginRec_(static_cast<std::uint_fast8_t>(rec_)); \
|
|
QS_TIME_PRE_(); {
|
|
|
|
//${QS-macros::QS_END} .......................................................
|
|
#define QS_END() } \
|
|
QP::QS::endRec_(); \
|
|
QS_MEM_APP(); \
|
|
QS_CRIT_EXIT(); \
|
|
}
|
|
|
|
//${QS-macros::QS_FLUSH} .....................................................
|
|
#define QS_FLUSH() (QP::QS::onFlush())
|
|
|
|
//${QS-macros::QS_BEGIN_INCRIT} ..............................................
|
|
#define QS_BEGIN_INCRIT(rec_, qsId_) \
|
|
if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qsId_)) { \
|
|
QP::QS::beginRec_(rec_); \
|
|
QS_TIME_PRE_(); {
|
|
|
|
//${QS-macros::QS_END_INCRIT} ................................................
|
|
#define QS_END_INCRIT() } \
|
|
QP::QS::endRec_(); \
|
|
}
|
|
|
|
//${QS-macros::QS_GLB_CHECK_} ................................................
|
|
#define QS_GLB_CHECK_(rec_) \
|
|
((static_cast<std::uint_fast8_t>(QP::QS::filt_.glb[ \
|
|
static_cast<std::uint_fast8_t>(rec_) >> 3U]) \
|
|
& (static_cast<std::uint_fast8_t>(1U) \
|
|
<< (static_cast<std::uint_fast8_t>(rec_) & 7U))) != 0U)
|
|
|
|
//${QS-macros::QS_LOC_CHECK_} ................................................
|
|
#define QS_LOC_CHECK_(qsId_) \
|
|
((static_cast<std::uint_fast8_t>(QP::QS::filt_.loc \
|
|
[static_cast<std::uint_fast8_t>(qsId_) >> 3U]) \
|
|
& (static_cast<std::uint_fast8_t>(1U) \
|
|
<< (static_cast<std::uint_fast8_t>(qsId_) & 7U))) != 0U)
|
|
|
|
//${QS-macros::QS_REC_DONE} ..................................................
|
|
#ifndef QS_REC_DONE
|
|
#define QS_REC_DONE() (static_cast<void>(0))
|
|
#endif // ndef QS_REC_DONE
|
|
|
|
//${QS-macros::QS_I8} ........................................................
|
|
#define QS_I8(width_, data_) \
|
|
(QP::QS::u8_fmt_(static_cast<std::uint8_t>( \
|
|
(static_cast<std::uint8_t>(((width_) << 4U) & 0x7U)) \
|
|
| static_cast<std::uint8_t>(QP::QS::I8_ENUM_T)), (data_)))
|
|
|
|
//${QS-macros::QS_U8} ........................................................
|
|
#define QS_U8(width_, data_) \
|
|
(QP::QS::u8_fmt_(static_cast<std::uint8_t>( \
|
|
(static_cast<std::uint8_t>((width_) << 4U)) \
|
|
| static_cast<std::uint8_t>(QP::QS::U8_T)), (data_)))
|
|
|
|
//${QS-macros::QS_I16} .......................................................
|
|
#define QS_I16(width_, data_) \
|
|
(QP::QS::u16_fmt_(static_cast<std::uint8_t>( \
|
|
(static_cast<std::uint8_t>((width_) << 4U)) \
|
|
| static_cast<std::uint8_t>(QP::QS::I16_T)), (data_)))
|
|
|
|
//${QS-macros::QS_U16} .......................................................
|
|
#define QS_U16(width_, data_) \
|
|
(QP::QS::u16_fmt_(static_cast<std::uint8_t>((((width_) << 4U)) \
|
|
| static_cast<std::uint8_t>(QP::QS::U16_T)), (data_)))
|
|
|
|
//${QS-macros::QS_I32} .......................................................
|
|
#define QS_I32(width_, data_) \
|
|
(QP::QS::u32_fmt_( \
|
|
static_cast<std::uint8_t>((static_cast<std::uint8_t>((width_) << 4U)) \
|
|
| static_cast<std::uint8_t>(QP::QS::I32_T)), (data_)))
|
|
|
|
//${QS-macros::QS_U32} .......................................................
|
|
#define QS_U32(width_, data_) \
|
|
(QP::QS::u32_fmt_(static_cast<std::uint8_t>( \
|
|
(static_cast<std::uint8_t>((width_) << 4U)) \
|
|
| static_cast<std::uint8_t>(QP::QS::U32_T)), (data_)))
|
|
|
|
//${QS-macros::QS_I64} .......................................................
|
|
#define QS_I64(width_, data_) \
|
|
(QP::QS::u64_fmt_(static_cast<std::uint8_t>( \
|
|
(static_cast<std::uint8_t>((width_) << 4U)) \
|
|
| static_cast<std::uint8_t>(QP::QS::I64_T)), (data_)))
|
|
|
|
//${QS-macros::QS_U64} .......................................................
|
|
#define QS_U64(width_, data_) \
|
|
(QP::QS::u64_fmt_(static_cast<std::uint8_t>( \
|
|
(static_cast<std::uint8_t>((width_) << 4U)) \
|
|
| static_cast<std::uint8_t>(QP::QS::U64_T)), (data_)))
|
|
|
|
//${QS-macros::QS_F32} .......................................................
|
|
#define QS_F32(width_, data_) \
|
|
(QP::QS::f32_fmt_(static_cast<std::uint8_t>( \
|
|
(static_cast<std::uint8_t>((width_) << 4U)) \
|
|
| static_cast<std::uint8_t>(QP::QS::F32_T)), (data_)))
|
|
|
|
//${QS-macros::QS_F64} .......................................................
|
|
#define QS_F64(width_, data_) \
|
|
(QP::QS::f64_fmt_(static_cast<std::uint8_t>( \
|
|
(static_cast<std::uint8_t>((width_) << 4U)) \
|
|
| static_cast<std::uint8_t>(QP::QS::F64_T)), (data_)))
|
|
|
|
//${QS-macros::QS_STR} .......................................................
|
|
#define QS_STR(str_) (QP::QS::str_fmt_(str_))
|
|
|
|
//${QS-macros::QS_MEM} .......................................................
|
|
#define QS_MEM(mem_, size_) (QP::QS::mem_fmt_((mem_), (size_)))
|
|
|
|
//${QS-macros::QS_ENUM} ......................................................
|
|
#define QS_ENUM(group_, value_) \
|
|
(QP::QS::u8_fmt_(static_cast<std::uint8_t>(0x80U | ((group_) << 4U)) \
|
|
| static_cast<std::uint8_t>(QP::QS::I8_ENUM_T),\
|
|
static_cast<std::uint8_t>(value_)))
|
|
|
|
//${QS-macros::QS_TIME_PRE_} .................................................
|
|
#if (QS_TIME_SIZE == 2U)
|
|
#define QS_TIME_PRE_() (QP::QS::u16_raw_(QP::QS::onGetTime()))
|
|
#endif // (QS_TIME_SIZE == 2U)
|
|
|
|
//${QS-macros::QS_TIME_PRE_} .................................................
|
|
#if (QS_TIME_SIZE == 4U)
|
|
#define QS_TIME_PRE_() (QP::QS::u32_raw_(QP::QS::onGetTime()))
|
|
#endif // (QS_TIME_SIZE == 4U)
|
|
|
|
//${QS-macros::QS_OBJ} .......................................................
|
|
#if (QS_OBJ_PTR_SIZE == 2U)
|
|
#define QS_OBJ(obj_) (QP::QS::u16_fmt_(QP::QS::OBJ_T, \
|
|
reinterpret_cast<std::uint16_t>(obj_)))
|
|
#endif // (QS_OBJ_PTR_SIZE == 2U)
|
|
|
|
//${QS-macros::QS_OBJ} .......................................................
|
|
#if (QS_OBJ_PTR_SIZE == 4U)
|
|
#define QS_OBJ(obj_) (QP::QS::u32_fmt_(QP::QS::OBJ_T, \
|
|
reinterpret_cast<std::uint32_t>(obj_)))
|
|
#endif // (QS_OBJ_PTR_SIZE == 4U)
|
|
|
|
//${QS-macros::QS_OBJ} .......................................................
|
|
#if (QS_OBJ_PTR_SIZE == 8U)
|
|
#define QS_OBJ(obj_) (QP::QS::u64_fmt_(QP::QS::OBJ_T, \
|
|
reinterpret_cast<std::uint64_t>(obj_)))
|
|
#endif // (QS_OBJ_PTR_SIZE == 8U)
|
|
|
|
//${QS-macros::QS_FUN} .......................................................
|
|
#if (QS_FUN_PTR_SIZE == 2U)
|
|
#define QS_FUN(fun_) (QP::QS::u16_fmt_(QP::QS::FUN_T, \
|
|
reinterpret_cast<std::uint16_t>(fun_)))
|
|
#endif // (QS_FUN_PTR_SIZE == 2U)
|
|
|
|
//${QS-macros::QS_FUN} .......................................................
|
|
#if (QS_FUN_PTR_SIZE == 4U)
|
|
#define QS_FUN(fun_) (QP::QS::u32_fmt_(QP::QS::FUN_T, \
|
|
reinterpret_cast<std::uint32_t>(fun_)))
|
|
#endif // (QS_FUN_PTR_SIZE == 4U)
|
|
|
|
//${QS-macros::QS_FUN} .......................................................
|
|
#if (QS_FUN_PTR_SIZE == 8U)
|
|
#define QS_FUN(fun_) (QP::QS::u64_fmt_(QP::QS::FUN_T, \
|
|
reinterpret_cast<std::uint64_t>(fun_)))
|
|
#endif // (QS_FUN_PTR_SIZE == 8U)
|
|
|
|
//${QS-macros::QS_SIG} .......................................................
|
|
#if (Q_SIGNAL_SIZE == 1U)
|
|
#define QS_SIG(sig_, obj_) \
|
|
QP::QS::u8_fmt_(QP::QS::SIG_T, static_cast<std::uint8_t>(sig_)); \
|
|
QP::QS::obj_raw_(obj_)
|
|
#endif // (Q_SIGNAL_SIZE == 1U)
|
|
|
|
//${QS-macros::QS_SIG} .......................................................
|
|
#if (Q_SIGNAL_SIZE == 2U)
|
|
#define QS_SIG(sig_, obj_) \
|
|
QP::QS::u16_fmt_(QP::QS::SIG_T, static_cast<std::uint16_t>(sig_)); \
|
|
QP::QS::obj_raw_(obj_)
|
|
#endif // (Q_SIGNAL_SIZE == 2U)
|
|
|
|
//${QS-macros::QS_SIG} .......................................................
|
|
#if (Q_SIGNAL_SIZE == 4U)
|
|
#define QS_SIG(sig_, obj_) \
|
|
QP::QS::u32_fmt_(QP::QS::SIG_T, static_cast<std::uint32_t>(sig_)); \
|
|
QP::QS::obj_raw_(obj_)
|
|
#endif // (Q_SIGNAL_SIZE == 4U)
|
|
|
|
//${QS-macros::QS_SIG_DICTIONARY} ............................................
|
|
#define QS_SIG_DICTIONARY(sig_, obj_) \
|
|
(QP::QS::sig_dict_pre_((sig_), (obj_), #sig_))
|
|
|
|
//${QS-macros::QS_OBJ_DICTIONARY} ............................................
|
|
#define QS_OBJ_DICTIONARY(obj_) \
|
|
(QP::QS::obj_dict_pre_((obj_), #obj_))
|
|
|
|
//${QS-macros::QS_OBJ_ARR_DICTIONARY} ........................................
|
|
#define QS_OBJ_ARR_DICTIONARY(obj_, idx_) \
|
|
(QP::QS::obj_arr_dict_pre_((obj_), (idx_), #obj_))
|
|
|
|
//${QS-macros::QS_FUN_DICTIONARY} ............................................
|
|
#define QS_FUN_DICTIONARY(fun_) \
|
|
(QP::QS::fun_dict_pre_( \
|
|
QP::QS::force_cast<void (*)()>(fun_), #fun_))
|
|
|
|
//${QS-macros::QS_USR_DICTIONARY} ............................................
|
|
#define QS_USR_DICTIONARY(rec_) \
|
|
(QP::QS::usr_dict_pre_((rec_), #rec_))
|
|
|
|
//${QS-macros::QS_ENUM_DICTIONARY} ...........................................
|
|
#define QS_ENUM_DICTIONARY(value_, group_) \
|
|
(QP::QS::enum_dict_pre_((value_), (group_), #value_))
|
|
|
|
//${QS-macros::QS_QF_CRIT_ENTRY} .............................................
|
|
#define QS_QF_CRIT_ENTRY() (QP::QS::crit_entry_pre_())
|
|
|
|
//${QS-macros::QS_QF_CRIT_EXIT} ..............................................
|
|
#define QS_QF_CRIT_EXIT() (QP::QS::crit_exit_pre_())
|
|
|
|
//${QS-macros::QS_QF_ISR_ENTRY} ..............................................
|
|
#define QS_QF_ISR_ENTRY(isrnest_, prio_) \
|
|
(QP::QS::isr_entry_pre_((isrnest_), (prio_)))
|
|
|
|
//${QS-macros::QS_QF_ISR_EXIT} ...............................................
|
|
#define QS_QF_ISR_EXIT(isrnest_, prio_) \
|
|
(QP::QS::isr_exit_pre_((isrnest_), (prio_)))
|
|
|
|
//${QS-macros::QS_ONLY} ......................................................
|
|
#define QS_ONLY(code_) (code_)
|
|
|
|
//${QS-macros::QS_ASSERTION} .................................................
|
|
#define QS_ASSERTION(module_, id_, delay_) \
|
|
(QP::QS::assertion_pre_((module_), (id_), (delay_)))
|
|
|
|
//${QS-macros::QS_EOD} .......................................................
|
|
#define QS_EOD (static_cast<std::uint16_t>(0xFFFFU))
|
|
|
|
//${QS-macros::QS_CMD} .......................................................
|
|
#define QS_CMD (static_cast<std::uint8_t>(7U))
|
|
|
|
//${QS-macros::QS_HEX_FMT} ...................................................
|
|
#define QS_HEX_FMT (static_cast<std::uint8_t>(0x0FU))
|
|
|
|
//${QS-macros::QS_CRIT_STAT} .................................................
|
|
#ifndef QS_CRIT_STAT
|
|
#define QS_CRIT_STAT QF_CRIT_STAT
|
|
#endif // ndef QS_CRIT_STAT
|
|
|
|
//${QS-macros::QS_CRIT_ENTRY} ................................................
|
|
#ifndef QS_CRIT_ENTRY
|
|
#define QS_CRIT_ENTRY() QF_CRIT_ENTRY()
|
|
#endif // ndef QS_CRIT_ENTRY
|
|
|
|
//${QS-macros::QS_CRIT_EXIT} .................................................
|
|
#ifndef QS_CRIT_EXIT
|
|
#define QS_CRIT_EXIT() QF_CRIT_EXIT()
|
|
#endif // ndef QS_CRIT_EXIT
|
|
|
|
//${QS-macros::QS_MEM_SYS} ...................................................
|
|
#ifndef QS_MEM_SYS
|
|
#define QS_MEM_SYS() QF_MEM_SYS()
|
|
#endif // ndef QS_MEM_SYS
|
|
|
|
//${QS-macros::QS_MEM_APP} ...................................................
|
|
#ifndef QS_MEM_APP
|
|
#define QS_MEM_APP() QF_MEM_APP()
|
|
#endif // ndef QS_MEM_APP
|
|
//$enddecl${QS-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
//============================================================================
|
|
//! @cond INTERNAL
|
|
|
|
namespace QP {
|
|
namespace QS {
|
|
|
|
struct Attr {
|
|
void const * locFilter_AP; //!< @deprecated
|
|
std::uint8_t * buf;
|
|
QSCtr end;
|
|
QSCtr volatile head;
|
|
QSCtr volatile tail;
|
|
QSCtr volatile used;
|
|
std::uint8_t volatile seq;
|
|
std::uint8_t volatile chksum;
|
|
std::uint8_t volatile critNest;
|
|
std::uint8_t flags;
|
|
};
|
|
|
|
extern Attr priv_;
|
|
|
|
void glbFilter_(std::int_fast16_t const filter) noexcept;
|
|
void locFilter_(std::int_fast16_t const filter) noexcept;
|
|
|
|
void beginRec_(std::uint_fast8_t const rec) noexcept;
|
|
void endRec_() noexcept;
|
|
|
|
void u8_raw_(std::uint8_t const d) noexcept;
|
|
void u8u8_raw_(std::uint8_t const d1, std::uint8_t const d2) noexcept;
|
|
void u16_raw_(std::uint16_t d) noexcept;
|
|
void u32_raw_(std::uint32_t d) noexcept;
|
|
void u64_raw_(std::uint64_t d) noexcept;
|
|
void obj_raw_(void const * const obj) noexcept;
|
|
void str_raw_(char const * s) noexcept;
|
|
|
|
void u8_fmt_(std::uint8_t const format, std::uint8_t const d) noexcept;
|
|
void u16_fmt_(std::uint8_t format, std::uint16_t d) noexcept;
|
|
void u32_fmt_(std::uint8_t format,
|
|
std::uint32_t d) noexcept;
|
|
void u64_fmt_(std::uint8_t format, std::uint64_t d) noexcept;
|
|
void f32_fmt_(std::uint8_t format, float32_t f) noexcept;
|
|
void f64_fmt_(std::uint8_t format, float64_t d) noexcept;
|
|
void str_fmt_(char const * s) noexcept;
|
|
void mem_fmt_(std::uint8_t const * blk, std::uint8_t size) noexcept;
|
|
|
|
void sig_dict_pre_(QSignal const sig, void const * const obj,
|
|
char const * const name) noexcept;
|
|
void obj_dict_pre_(void const * const obj,
|
|
char const * const name) noexcept;
|
|
void obj_arr_dict_pre_(void const * const obj,
|
|
std::uint_fast16_t const idx,
|
|
char const * const name) noexcept;
|
|
void fun_dict_pre_(QSpyFunPtr fun,
|
|
char const * const name) noexcept;
|
|
void usr_dict_pre_(enum_t const rec, char const * const name) noexcept;
|
|
void enum_dict_pre_(enum_t const value, std::uint8_t const group,
|
|
char const * const name) noexcept;
|
|
|
|
void assertion_pre_(char const * const module, int_t const id,
|
|
std::uint32_t const delay) noexcept;
|
|
void crit_entry_pre_() noexcept;
|
|
void crit_exit_pre_() noexcept;
|
|
void isr_entry_pre_(std::uint8_t const isrnest,
|
|
std::uint8_t const prio) noexcept;
|
|
void isr_exit_pre_(std::uint8_t const isrnest,
|
|
std::uint8_t const prio) noexcept;
|
|
|
|
void target_info_pre_(std::uint8_t const isReset);
|
|
|
|
} // namespace QS
|
|
} // namespace QP
|
|
|
|
//! @endcond
|
|
//============================================================================
|
|
|
|
//$declare${QS::QS-TX} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
|
namespace QP {
|
|
namespace QS {
|
|
|
|
//${QS::QS-TX::preType} ......................................................
|
|
//! Enumerates data elements for app-specific trace records
|
|
enum preType : std::uint8_t {
|
|
I8_ENUM_T, //!< signed 8-bit integer or enum format
|
|
U8_T, //!< unsigned 8-bit integer format
|
|
I16_T, //!< signed 16-bit integer format
|
|
U16_T, //!< unsigned 16-bit integer format
|
|
I32_T, //!< signed 32-bit integer format
|
|
U32_T, //!< unsigned 32-bit integer format
|
|
F32_T, //!< 32-bit floating point format
|
|
F64_T, //!< 64-bit floating point format
|
|
STR_T, //!< zero-terminated ASCII string format
|
|
MEM_T, //!< up to 255-bytes memory block format
|
|
SIG_T, //!< event signal format
|
|
OBJ_T, //!< object pointer format
|
|
FUN_T, //!< function pointer format
|
|
I64_T, //!< signed 64-bit integer format
|
|
U64_T //!< unsigned 64-bit integer format
|
|
};
|
|
|
|
//${QS::QS-TX::force_cast} ...................................................
|
|
template<typename T_OUT, typename T_IN>
|
|
inline T_OUT force_cast(T_IN in) {
|
|
union TCast {
|
|
T_IN in;
|
|
T_OUT out;
|
|
} u = { in };
|
|
return u.out;
|
|
}
|
|
|
|
//${QS::QS-TX::initBuf} ......................................................
|
|
void initBuf(
|
|
std::uint8_t * const sto,
|
|
std::uint_fast32_t const stoSize) noexcept;
|
|
|
|
//${QS::QS-TX::getByte} ......................................................
|
|
std::uint16_t getByte() noexcept;
|
|
|
|
//${QS::QS-TX::getBlock} .....................................................
|
|
std::uint8_t const * getBlock(std::uint16_t * const pNbytes) noexcept;
|
|
|
|
//${QS::QS-TX::doOutput} .....................................................
|
|
void doOutput();
|
|
|
|
//${QS::QS-TX::onStartup} ....................................................
|
|
bool onStartup(void const * arg);
|
|
|
|
//${QS::QS-TX::onCleanup} ....................................................
|
|
void onCleanup();
|
|
|
|
//${QS::QS-TX::onFlush} ......................................................
|
|
void onFlush();
|
|
|
|
//${QS::QS-TX::onGetTime} ....................................................
|
|
QSTimeCtr onGetTime();
|
|
|
|
} // namespace QS
|
|
} // namespace QP
|
|
//$enddecl${QS::QS-TX} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
//============================================================================
|
|
#ifdef Q_UTEST
|
|
|
|
//$declare${QS::QUTest} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
|
namespace QP {
|
|
namespace QS {
|
|
|
|
//${QS::QUTest::TProbe} ......................................................
|
|
struct TProbe {
|
|
QSFun addr;
|
|
std::uint32_t data;
|
|
std::uint8_t idx;
|
|
};
|
|
|
|
//${QS::QUTest::onTestSetup} .................................................
|
|
void onTestSetup();
|
|
|
|
//${QS::QUTest::onTestTeardown} ..............................................
|
|
void onTestTeardown();
|
|
|
|
//${QS::QUTest::onTestEvt} ...................................................
|
|
void onTestEvt(QEvt * e);
|
|
|
|
//${QS::QUTest::onTestPost} ..................................................
|
|
void onTestPost(
|
|
void const * sender,
|
|
QActive * recipient,
|
|
QEvt const * e,
|
|
bool status);
|
|
|
|
//${QS::QUTest::onTestLoop} ..................................................
|
|
void onTestLoop();
|
|
|
|
} // namespace QS
|
|
} // namespace QP
|
|
//$enddecl${QS::QUTest} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
#define QUTEST_ON_POST 124
|
|
|
|
//============================================================================
|
|
//! @cond INTERNAL
|
|
|
|
namespace QP {
|
|
namespace QS {
|
|
|
|
struct TestAttr {
|
|
TProbe tpBuf[16];
|
|
std::uint8_t tpNum;
|
|
QSTimeCtr testTime;
|
|
QPSet readySet;
|
|
QPSet readySet_dis;
|
|
std::uint_fast8_t intLock;
|
|
};
|
|
|
|
extern TestAttr tstPriv_;
|
|
|
|
void test_pause_();
|
|
std::uint32_t getTestProbe_(QSpyFunPtr const api) noexcept;
|
|
|
|
} // namespace QS
|
|
} // namespace QP
|
|
|
|
//! @endcond
|
|
//============================================================================
|
|
|
|
// QP-stub for QUTest
|
|
// NOTE: The QP-stub is needed for unit testing QP applications,
|
|
// but might NOT be needed for testing QP itself.
|
|
#if (Q_UTEST != 0)
|
|
|
|
//$declare${QS::QUTest-stub::QHsmDummy} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
|
namespace QP {
|
|
|
|
//${QS::QUTest-stub::QHsmDummy} ..............................................
|
|
class QHsmDummy : public QP::QAsm {
|
|
public:
|
|
QHsmDummy();
|
|
void init(
|
|
void const * const e,
|
|
std::uint_fast8_t const qsId) override;
|
|
void dispatch(
|
|
QEvt const * const e,
|
|
std::uint_fast8_t const qsId) override;
|
|
}; // class QHsmDummy
|
|
|
|
} // namespace QP
|
|
//$enddecl${QS::QUTest-stub::QHsmDummy} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
//$declare${QS::QUTest-stub::QActiveDummy} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
|
namespace QP {
|
|
|
|
//${QS::QUTest-stub::QActiveDummy} ...........................................
|
|
class QActiveDummy : public QP::QActive {
|
|
private:
|
|
friend class QActive;
|
|
|
|
public:
|
|
QActiveDummy();
|
|
void init(
|
|
void const * const e,
|
|
std::uint_fast8_t const qsId) override;
|
|
void dispatch(
|
|
QEvt const * const e,
|
|
std::uint_fast8_t const qsId) override;
|
|
|
|
private:
|
|
bool fakePost(
|
|
QEvt const * const e,
|
|
std::uint_fast16_t const margin,
|
|
void const * const sender) noexcept;
|
|
void fakePostLIFO(QEvt const * const e) noexcept;
|
|
}; // class QActiveDummy
|
|
|
|
} // namespace QP
|
|
//$enddecl${QS::QUTest-stub::QActiveDummy} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
#endif // Q_UTEST != 0
|
|
|
|
#define QS_TEST_PROBE_DEF(fun_) \
|
|
std::uint32_t const qs_tp_ = \
|
|
QP::QS::getTestProbe_(QP::QS::force_cast<void (*)()>(fun_));
|
|
|
|
#define QS_TEST_PROBE(code_) \
|
|
if (qs_tp_ != 0U) { code_ }
|
|
|
|
#define QS_TEST_PROBE_ID(id_, code_) \
|
|
if (qs_tp_ == static_cast<std::uint32_t>(id_)) { code_ }
|
|
|
|
#define QS_TEST_PAUSE() (QP::QS::test_pause_())
|
|
|
|
#else // Q_UTEST not defined
|
|
|
|
// dummy definitions when not building for QUTEST
|
|
#define QS_TEST_PROBE_DEF(fun_)
|
|
#define QS_TEST_PROBE(code_)
|
|
#define QS_TEST_PROBE_ID(id_, code_)
|
|
#define QS_TEST_PAUSE() (static_cast<void>(0))
|
|
|
|
#endif // Q_UTEST
|
|
|
|
//============================================================================
|
|
//! @cond INTERNAL
|
|
|
|
namespace QP {
|
|
namespace QS {
|
|
|
|
//............................................................................
|
|
struct CmdVar {
|
|
std::uint32_t param1;
|
|
std::uint32_t param2;
|
|
std::uint32_t param3;
|
|
std::uint8_t idx;
|
|
std::uint8_t cmdId;
|
|
};
|
|
|
|
struct TickVar {
|
|
std::uint_fast8_t rate;
|
|
};
|
|
|
|
struct PeekVar {
|
|
std::uint16_t offs;
|
|
std::uint8_t size;
|
|
std::uint8_t num;
|
|
std::uint8_t idx;
|
|
};
|
|
|
|
struct PokeVar {
|
|
std::uint32_t data;
|
|
std::uint16_t offs;
|
|
std::uint8_t size;
|
|
std::uint8_t num;
|
|
std::uint8_t idx;
|
|
std::uint8_t fill;
|
|
};
|
|
|
|
struct FltVar {
|
|
std::uint8_t data[16];
|
|
std::uint8_t idx;
|
|
std::uint8_t recId; // global/local
|
|
};
|
|
|
|
struct ObjVar {
|
|
QSObj addr;
|
|
std::uint8_t idx;
|
|
std::uint8_t kind; // see qs.hpp, enum QSpyObjKind
|
|
std::uint8_t recId;
|
|
};
|
|
|
|
struct EvtVar {
|
|
QP::QEvt *e;
|
|
std::uint8_t *p;
|
|
QP::QSignal sig;
|
|
std::uint16_t len;
|
|
std::uint8_t prio;
|
|
std::uint8_t idx;
|
|
};
|
|
|
|
struct RxAttr {
|
|
void * currObj[8];
|
|
std::uint8_t * buf;
|
|
QSCtr end;
|
|
QSCtr volatile head;
|
|
QSCtr volatile tail;
|
|
std::uint8_t state;
|
|
std::uint8_t esc;
|
|
std::uint8_t seq;
|
|
std::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
|
|
QP::QS::TProbe tp;
|
|
#endif // Q_UTEST
|
|
} var;
|
|
} ;
|
|
|
|
extern RxAttr rxPriv_;
|
|
|
|
} // namespace QS
|
|
} // namespace QP
|
|
|
|
//! @endcond
|
|
//============================================================================
|
|
|
|
//$declare${QS::QS-RX} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
|
namespace QP {
|
|
namespace QS {
|
|
|
|
//${QS::QS-RX::QSpyObjKind} ..................................................
|
|
//! Kinds of objects used QS-RX
|
|
enum QSpyObjKind : std::uint8_t {
|
|
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::OSpyObjCombnation} ............................................
|
|
//! Object combinations for QS-RX
|
|
enum OSpyObjCombnation : std::uint8_t {
|
|
SM_AO_OBJ = MAX_OBJ //!< combination of SM and AO
|
|
};
|
|
|
|
//${QS::QS-RX::rxInitBuf} ....................................................
|
|
void rxInitBuf(
|
|
std::uint8_t * const sto,
|
|
std::uint16_t const stoSize) noexcept;
|
|
|
|
//${QS::QS-RX::rxPut} ........................................................
|
|
inline bool rxPut(std::uint8_t const b) noexcept {
|
|
// NOTE: does not need critical section
|
|
// But requires system-level memory access (QF_MEM_SYS()).
|
|
|
|
QSCtr head = rxPriv_.head + 1U;
|
|
if (head == rxPriv_.end) {
|
|
head = 0U;
|
|
}
|
|
if (head != rxPriv_.tail) { // buffer NOT full?
|
|
rxPriv_.buf[rxPriv_.head] = b;
|
|
rxPriv_.head = head;
|
|
return true; // byte placed in the buffer
|
|
}
|
|
else {
|
|
return false; // byte NOT placed in the buffer
|
|
}
|
|
}
|
|
|
|
//${QS::QS-RX::rxParse} ......................................................
|
|
void rxParse();
|
|
|
|
//${QS::QS-RX::setCurrObj} ...................................................
|
|
void setCurrObj(
|
|
std::uint8_t const obj_kind,
|
|
void * const obj_ptr);
|
|
|
|
//${QS::QS-RX::rxGetNfree} ...................................................
|
|
std::uint16_t rxGetNfree() noexcept;
|
|
|
|
//${QS::QS-RX::doInput} ......................................................
|
|
void doInput();
|
|
|
|
//${QS::QS-RX::onReset} ......................................................
|
|
void onReset();
|
|
|
|
//${QS::QS-RX::onCommand} ....................................................
|
|
void onCommand(
|
|
std::uint8_t cmdId,
|
|
std::uint32_t param1,
|
|
std::uint32_t param2,
|
|
std::uint32_t param3);
|
|
|
|
} // namespace QS
|
|
} // namespace QP
|
|
//$enddecl${QS::QS-RX} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
#endif // QS_HPP_
|