qpcpp/qpcpp.qm
MMS 4028ad2dd6 7.3.5-rc.1
Semantic versioning
2024-06-05 08:50:09 -04:00

12332 lines
439 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<model version="6.1.1" links="1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.state-machine.com/qm/qm.xsd">
<documentation>QP/C++ Real-Time Embedded Framework (RTEF)
The model is used to generate the whole QP/C++ source code.
Copyright (C) 2005 Quantum Leaps, LLC &lt;state-machine.com&gt;.
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: &lt;www.gnu.org/licenses/gpl-3.0&gt;
The terms of the closed source Quantum Leaps commercial licenses
can be found at: &lt;www.state-machine.com/licensing&gt;
Redistributions in source code must retain this copyright notice.
Plagiarizing this software to sidestep the license obligations is illegal.
Contact information:
&lt;www.state-machine.com/licensing&gt;
&lt;info@state-machine.com&gt;</documentation>
<!--${qpcpp}-->
<framework name="qpcpp" license="LICENSES/LicenseRef-QL-dual.qlc"/>
<!--${glob-types}-->
<package name="glob-types" stereotype="0x00">
<!--${glob-types::int_t}-->
<attribute name="int_t" type="using" visibility="0x04" properties="0x00">
<code> = int;</code>
</attribute>
<!--${glob-types::enum_t}-->
<attribute name="enum_t" type="using" visibility="0x04" properties="0x00">
<code> = int;</code>
</attribute>
<!--${glob-types::float32_t}-->
<attribute name="float32_t" type="using" visibility="0x04" properties="0x00">
<code> = float;</code>
</attribute>
<!--${glob-types::float64_t}-->
<attribute name="float64_t" type="using" visibility="0x04" properties="0x00">
<code> = double;</code>
</attribute>
</package>
<!--${QEP}-->
<package name="QEP" stereotype="0x05" namespace="QP::">
<!--${QEP::versionStr[]}-->
<attribute name="versionStr[]" type="constexpr char const" visibility="0x04" properties="0x01">
<code>{QP_VERSION_STR};</code>
</attribute>
<!--${QEP::QSignal}-->
<attribute name="QSignal? (Q_SIGNAL_SIZE == 1U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint8_t;</code>
</attribute>
<!--${QEP::QSignal}-->
<attribute name="QSignal? (Q_SIGNAL_SIZE == 2U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint16_t;</code>
</attribute>
<!--${QEP::QSignal}-->
<attribute name="QSignal? (Q_SIGNAL_SIZE == 4U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint32_t;</code>
</attribute>
<!--${QEP::QEvt}-->
<class name="QEvt">
<!--${QEP::QEvt::sig}-->
<attribute name="sig" type="QSignal" visibility="0x00" properties="0x00"/>
<!--${QEP::QEvt::refCtr_}-->
<attribute name="refCtr_" type="std::uint8_t volatile" visibility="0x00" properties="0x00"/>
<!--${QEP::QEvt::evtTag_}-->
<attribute name="evtTag_" type="std::uint8_t" visibility="0x00" properties="0x00"/>
<!--${QEP::QEvt::MARKER}-->
<attribute name="MARKER" type="static constexpr std::uint8_t" visibility="0x04" properties="0x01">
<code> {0xE0U};</code>
</attribute>
<!--${QEP::QEvt::DynEvt}-->
<attribute name="DynEvt?def QEVT_DYN_CTOR" type="enum" visibility="0x04" properties="0x00">
<code>: std::uint8_t { DYNAMIC };</code>
</attribute>
<!--${QEP::QEvt::ctor}-->
<operation name="ctor?def QEVT_DYN_CTOR" type="QEvt *" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QEP::QEvt::ctor::dummy}-->
<parameter name="dummy" type="DynEvt const"/>
<code>Q_UNUSED_PAR(dummy);
return this;</code>
</operation>
<!--${QEP::QEvt::QEvt}-->
<operation name="QEvt" type="explicit constexpr" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QEvt::QEvt::s}-->
<parameter name="s" type="QSignal const"/>
<code> : sig(s),
refCtr_(0U),
evtTag_(MARKER)</code>
</operation>
<!--${QEP::QEvt::QEvt}-->
<operation name="QEvt" type="" visibility="0x00" properties="0x00">
<specifiers>= delete</specifiers>
</operation>
<!--${QEP::QEvt::verify_}-->
<operation name="verify_" type="bool" visibility="0x00" properties="0x03">
<specifiers>noexcept</specifiers>
<!--${QEP::QEvt::verify_::e}-->
<parameter name="e" type="QEvt const * const"/>
<code>return (e != nullptr)
&amp;&amp; ((e-&gt;evtTag_ &amp; 0xF0U) == MARKER);</code>
</operation>
<!--${QEP::QEvt::getPoolNum_}-->
<operation name="getPoolNum_" type="std::uint_fast8_t" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return static_cast&lt;std::uint8_t&gt;(evtTag_) &amp; 0x0FU;</code>
</operation>
</class>
<!--${QEP::QState}-->
<attribute name="QState" type="using" visibility="0x04" properties="0x00">
<code>= std::uint_fast8_t;</code>
</attribute>
<!--${QEP::QStateHandler}-->
<attribute name="QStateHandler" type="using" visibility="0x04" properties="0x00">
<code>= QState (*)(void * const me, QEvt const * const e);</code>
</attribute>
<!--${QEP::QActionHandler}-->
<attribute name="QActionHandler" type="using" visibility="0x04" properties="0x00">
<code>= QState (*)(void * const me);</code>
</attribute>
<!--${QEP::QXThread}-->
<attribute name="QXThread" type="class" visibility="0x04" properties="0x00">
<documentation>// forward declaration</documentation>
</attribute>
<!--${QEP::QXThreadHandler}-->
<attribute name="QXThreadHandler" type="using" visibility="0x04" properties="0x00">
<code>= void (*)(QXThread * const me);</code>
</attribute>
<!--${QEP::QMState}-->
<attribute name="QMState" type="struct" visibility="0x04" properties="0x00">
<code>{
QMState const * superstate;
QStateHandler const stateHandler;
QActionHandler const entryAction;
QActionHandler const exitAction;
QActionHandler const initAction;
};</code>
</attribute>
<!--${QEP::QMTranActTable}-->
<attribute name="QMTranActTable" type="struct" visibility="0x04" properties="0x00">
<code>{
QMState const * target;
QActionHandler const act[1];
};</code>
</attribute>
<!--${QEP::QAsmAttr}-->
<attribute name="QAsmAttr" type="union" visibility="0x04" properties="0x00">
<code>{
QStateHandler fun;
QActionHandler act;
QXThreadHandler thr;
QMState const *obj;
QMTranActTable const *tatbl;
#ifndef Q_UNSAFE
std::uintptr_t uint;
#endif
constexpr QAsmAttr() : fun(nullptr) {}
};</code>
</attribute>
<!--${QEP::Q_USER_SIG}-->
<attribute name="Q_USER_SIG" type="constexpr enum_t " visibility="0x04" properties="0x00">
<code>{4};</code>
</attribute>
<!--${QEP::QAsm}-->
<class name="QAsm">
<documentation>Abstract State Machine</documentation>
<!--${QEP::QAsm::m_state}-->
<attribute name="m_state" type="QAsmAttr" visibility="0x01" properties="0x00"/>
<!--${QEP::QAsm::m_temp}-->
<attribute name="m_temp" type="QAsmAttr" visibility="0x01" properties="0x00"/>
<!--${QEP::QAsm::QStateRet}-->
<attribute name="QStateRet" type="enum" visibility="0x04" properties="0x01">
<documentation>//! All possible return values from state-handlers
//! @note
//! The order is important for algorithmic correctness.</documentation>
<code> : QState {
// unhandled and need to &quot;bubble up&quot;
Q_RET_SUPER, //!&lt; event passed to superstate to handle
Q_RET_SUPER_SUB, //!&lt; event passed to submachine superstate
Q_RET_UNHANDLED, //!&lt; event unhandled due to a guard
// handled and do not need to &quot;bubble up&quot;
Q_RET_HANDLED, //!&lt; event handled (internal transition)
Q_RET_IGNORED, //!&lt; event silently ignored (bubbled up to top)
// entry/exit
Q_RET_ENTRY, //!&lt; state entry action executed
Q_RET_EXIT, //!&lt; state exit action executed
// no side effects
Q_RET_NULL, //!&lt; return value without any effect
// transitions need to execute transition-action table in QP::QMsm
Q_RET_TRAN, //!&lt; regular transition
Q_RET_TRAN_INIT, //!&lt; initial transition in a state or submachine
Q_RET_TRAN_EP, //!&lt; entry-point transition into a submachine
// transitions that additionally clobber QHsm.m_state
Q_RET_TRAN_HIST, //!&lt; transition to history of a given state
Q_RET_TRAN_XP //!&lt; exit-point transition out of a submachine
};</code>
</attribute>
<!--${QEP::QAsm::ReservedSig}-->
<attribute name="ReservedSig" type="enum" visibility="0x04" properties="0x01">
<documentation>//! Reserved signals by the QP-framework.</documentation>
<code> : QSignal {
Q_EMPTY_SIG, //!&lt; signal to execute the default case
Q_ENTRY_SIG, //!&lt; signal for entry actions
Q_EXIT_SIG, //!&lt; signal for exit actions
Q_INIT_SIG //!&lt; signal for nested initial transitions
};</code>
</attribute>
<!--${QEP::QAsm::QAsm}-->
<operation name="QAsm" type="explicit" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<code> : m_state(),
m_temp ()</code>
</operation>
<!--${QEP::QAsm::~QAsm}-->
<operation name="~QAsm?def Q_XTOR" type="" visibility="0x00" properties="0x06">
<specifiers>noexcept</specifiers>
<code>// empty</code>
</operation>
<!--${QEP::QAsm::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x04">
<specifiers>= 0</specifiers>
<!--${QEP::QAsm::init::e}-->
<parameter name="e" type="void const * const"/>
<!--${QEP::QAsm::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
</operation>
<!--${QEP::QAsm::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x06">
<!--${QEP::QAsm::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>this-&gt;init(nullptr, qsId);</code>
</operation>
<!--${QEP::QAsm::dispatch}-->
<operation name="dispatch" type="void" visibility="0x00" properties="0x04">
<specifiers>= 0</specifiers>
<!--${QEP::QAsm::dispatch::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QEP::QAsm::dispatch::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
</operation>
<!--${QEP::QAsm::isIn}-->
<operation name="isIn" type="bool" visibility="0x00" properties="0x06">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::isIn::state}-->
<parameter name="state" type="QStateHandler const"/>
<code>static_cast&lt;void&gt;(state);
return false;</code>
</operation>
<!--${QEP::QAsm::state}-->
<operation name="state" type="QStateHandler" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_state.fun;</code>
</operation>
<!--${QEP::QAsm::stateObj}-->
<operation name="stateObj" type="QMState const *" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_state.obj;</code>
</operation>
<!--${QEP::QAsm::getStateHandler}-->
<operation name="getStateHandler?def Q_SPY" type="QStateHandler" visibility="0x00" properties="0x06">
<specifiers>noexcept</specifiers>
<code>return m_state.fun;</code>
</operation>
<!--${QEP::QAsm::top}-->
<operation name="top" type="QState" visibility="0x00" properties="0x03">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::top::me}-->
<parameter name="me" type="void * const"/>
<!--${QEP::QAsm::top::e}-->
<parameter name="e" type="QEvt const * const"/>
<code>static_cast&lt;void&gt;(me);
static_cast&lt;void&gt;(e);
return Q_RET_IGNORED; // the top state ignores all events</code>
</operation>
<!--${QEP::QAsm::tran}-->
<operation name="tran" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::tran::target}-->
<parameter name="target" type="QStateHandler const"/>
<code>m_temp.fun = target;
return Q_RET_TRAN;</code>
</operation>
<!--${QEP::QAsm::tran_hist}-->
<operation name="tran_hist" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::tran_hist::hist}-->
<parameter name="hist" type="QStateHandler const"/>
<code>m_temp.fun = hist;
return Q_RET_TRAN_HIST;</code>
</operation>
<!--${QEP::QAsm::super}-->
<operation name="super" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::super::superstate}-->
<parameter name="superstate" type="QStateHandler const"/>
<code>m_temp.fun = superstate;
return Q_RET_SUPER;</code>
</operation>
<!--${QEP::QAsm::qm_tran}-->
<operation name="qm_tran" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_tran::tatbl}-->
<parameter name="tatbl" type="void const * const"/>
<code>m_temp.tatbl = static_cast&lt;QP::QMTranActTable const *&gt;(tatbl);
return Q_RET_TRAN;</code>
</operation>
<!--${QEP::QAsm::qm_tran_init}-->
<operation name="qm_tran_init" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_tran_init::tatbl}-->
<parameter name="tatbl" type="void const * const"/>
<code>m_temp.tatbl = static_cast&lt;QP::QMTranActTable const *&gt;(tatbl);
return Q_RET_TRAN_INIT;</code>
</operation>
<!--${QEP::QAsm::qm_tran_hist}-->
<operation name="qm_tran_hist" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_tran_hist::hist}-->
<parameter name="hist" type="QMState const * const"/>
<!--${QEP::QAsm::qm_tran_hist::tatbl}-->
<parameter name="tatbl" type="void const * const"/>
<code>m_state.obj = hist;
m_temp.tatbl = static_cast&lt;QP::QMTranActTable const *&gt;(tatbl);
return Q_RET_TRAN_HIST;</code>
</operation>
<!--${QEP::QAsm::qm_tran_ep}-->
<operation name="qm_tran_ep" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_tran_ep::tatbl}-->
<parameter name="tatbl" type="void const * const"/>
<code>m_temp.tatbl = static_cast&lt;QP::QMTranActTable const *&gt;(tatbl);
return Q_RET_TRAN_EP;</code>
</operation>
<!--${QEP::QAsm::qm_tran_xp}-->
<operation name="qm_tran_xp" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_tran_xp::xp}-->
<parameter name="xp" type="QActionHandler const"/>
<!--${QEP::QAsm::qm_tran_xp::tatbl}-->
<parameter name="tatbl" type="void const * const"/>
<code>m_state.act = xp;
m_temp.tatbl = static_cast&lt;QP::QMTranActTable const *&gt;(tatbl);
return Q_RET_TRAN_XP;</code>
</operation>
<!--${QEP::QAsm::qm_entry}-->
<operation name="qm_entry?def Q_SPY" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_entry::s}-->
<parameter name="s" type="QMState const * const"/>
<code>m_temp.obj = s;
return Q_RET_ENTRY;</code>
</operation>
<!--${QEP::QAsm::qm_entry}-->
<operation name="qm_entry?ndef Q_SPY" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_entry::s}-->
<parameter name="s" type="QMState const * const"/>
<code>static_cast&lt;void&gt;(s); // unused parameter
return Q_RET_ENTRY;</code>
</operation>
<!--${QEP::QAsm::qm_exit}-->
<operation name="qm_exit?def Q_SPY" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_exit::s}-->
<parameter name="s" type="QMState const * const"/>
<code>m_temp.obj = s;
return Q_RET_EXIT;</code>
</operation>
<!--${QEP::QAsm::qm_exit}-->
<operation name="qm_exit?ndef Q_SPY" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_exit::s}-->
<parameter name="s" type="QMState const * const"/>
<code>static_cast&lt;void&gt;(s); // unused parameter
return Q_RET_EXIT;</code>
</operation>
<!--${QEP::QAsm::qm_sm_exit}-->
<operation name="qm_sm_exit" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_sm_exit::s}-->
<parameter name="s" type="QMState const * const"/>
<code>m_temp.obj = s;
return Q_RET_EXIT;</code>
</operation>
<!--${QEP::QAsm::qm_super_sub}-->
<operation name="qm_super_sub" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_super_sub::s}-->
<parameter name="s" type="QMState const * const"/>
<code>m_temp.obj = s;
return Q_RET_SUPER_SUB;</code>
</operation>
</class>
<!--${QEP::QHsm}-->
<class name="QHsm" superclass="QEP::QAsm">
<documentation>Human-generated State Machine</documentation>
<!--${QEP::QHsm::MAX_NEST_DEPTH_}-->
<attribute name="MAX_NEST_DEPTH_" type="static constexpr std::int_fast8_t" visibility="0x04" properties="0x01">
<code>{6};</code>
</attribute>
<!--${QEP::QHsm::QHsm}-->
<operation name="QHsm" type="explicit" visibility="0x01" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QEP::QHsm::QHsm::initial}-->
<parameter name="initial" type="QStateHandler const"/>
<code>: QAsm()
m_state.fun = Q_STATE_CAST(&amp;top);
m_temp.fun = initial;</code>
</operation>
<!--${QEP::QHsm::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x04">
<specifiers>override</specifiers>
<!--${QEP::QHsm::init::e}-->
<parameter name="e" type="void const * const"/>
<!--${QEP::QHsm::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>QF_CRIT_STAT
#ifdef Q_SPY
QS_CRIT_ENTRY();
QS_MEM_SYS();
if ((QS::priv_.flags &amp; 0x01U) == 0U) {
QS::priv_.flags |= 0x01U;
QS_MEM_APP();
QS_CRIT_EXIT();
QS_FUN_DICTIONARY(&amp;QP::QHsm::top);
}
else {
QS_MEM_APP();
QS_CRIT_EXIT();
}
#else
Q_UNUSED_PAR(qsId);
#endif
QStateHandler t = m_state.fun;
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(200, (m_temp.fun != nullptr)
&amp;&amp; (t == Q_STATE_CAST(&amp;top)));
QF_CRIT_EXIT();
// execute the top-most initial tran.
QState r = (*m_temp.fun)(this, Q_EVT_CAST(QEvt));
QF_CRIT_ENTRY();
// the top-most initial tran. must be taken
Q_ASSERT_INCRIT(210, r == Q_RET_TRAN);
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId)
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(t); // the source state
QS_FUN_PRE_(m_temp.fun); // the target of the initial tran.
QS_END_PRE_()
QS_MEM_APP();
QF_CRIT_EXIT();
// drill down into the state hierarchy with initial transitions...
do {
QStateHandler path[MAX_NEST_DEPTH_]; // tran entry path array
std::int_fast8_t ip = 0; // tran entry path index
path[0] = m_temp.fun;
static_cast&lt;void&gt;(QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
// note: ip is here the fixed upper loop bound
while ((m_temp.fun != t) &amp;&amp; (ip &lt; (MAX_NEST_DEPTH_ - 1))) {
++ip;
path[ip] = m_temp.fun;
static_cast&lt;void&gt;(QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
}
QF_CRIT_ENTRY();
// too many state nesting levels or &quot;malformed&quot; HSM
Q_ENSURE_INCRIT(220, ip &lt; MAX_NEST_DEPTH_);
QF_CRIT_EXIT();
m_temp.fun = path[0];
// retrace the entry path in reverse (desired) order...
// note: ip is the fixed upper loop bound
do {
// enter path[ip]
if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG)
== Q_RET_HANDLED)
{
QS_STATE_ENTRY_(path[ip], qsId);
}
--ip;
} while (ip &gt;= 0);
t = path[0]; // current state becomes the new source
r = QHSM_RESERVED_EVT_(t, Q_INIT_SIG); // execute initial tran.
#ifdef Q_SPY
if (r == Q_RET_TRAN) {
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId)
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(t); // the source state
QS_FUN_PRE_(m_temp.fun); // the target of the initial tran.
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();
}
#endif // Q_SPY
} while (r == Q_RET_TRAN);
QF_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qsId)
QS_TIME_PRE_(); // time stamp
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(t); // the new active state
QS_END_PRE_()
QS_MEM_APP();
QF_CRIT_EXIT();
m_state.fun = t; // change the current active state
#ifndef Q_UNSAFE
m_temp.uint = ~m_state.uint;
#endif</code>
</operation>
<!--${QEP::QHsm::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x06">
<specifiers>override</specifiers>
<!--${QEP::QHsm::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>this-&gt;init(nullptr, qsId);</code>
</operation>
<!--${QEP::QHsm::dispatch}-->
<operation name="dispatch" type="void" visibility="0x00" properties="0x04">
<specifiers>override</specifiers>
<!--${QEP::QHsm::dispatch::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QEP::QHsm::dispatch::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(qsId);
#endif
QStateHandler s = m_state.fun;
QStateHandler t = s;
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_INVARIANT_INCRIT(302, (s != Q_STATE_CAST(0))
&amp;&amp; (m_state.uint == static_cast&lt;std::uintptr_t&gt;(~m_temp.uint)));
Q_INVARIANT_INCRIT(303, QEvt::verify_(e));
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId)
QS_TIME_PRE_(); // time stamp
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(s); // the current state
QS_END_PRE_()
QS_MEM_APP();
QF_CRIT_EXIT();
// process the event hierarchically...
QState r;
m_temp.fun = s;
std::int_fast8_t ip = MAX_NEST_DEPTH_; // fixed upper loop bound
do {
s = m_temp.fun;
r = (*s)(this, e); // invoke state handler s
if (r == Q_RET_UNHANDLED) { // unhandled due to a guard?
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_UNHANDLED, qsId)
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(s); // the current state
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();
r = QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG); // superstate of s
}
--ip;
} while ((r == Q_RET_SUPER) &amp;&amp; (ip &gt; 0));
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(310, ip &gt; 0);
QF_CRIT_EXIT();
if (r &gt;= Q_RET_TRAN) { // regular tran. taken?
QStateHandler path[MAX_NEST_DEPTH_];
path[0] = m_temp.fun; // tran. target
path[1] = t; // current state
path[2] = s; // tran. source
// exit current state to tran. source s...
ip = MAX_NEST_DEPTH_; // fixed upper loop bound
for (; (t != s) &amp;&amp; (ip &gt; 0); t = m_temp.fun) {
// exit from t
if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG) == Q_RET_HANDLED) {
QS_STATE_EXIT_(t, qsId);
// find superstate of t
static_cast&lt;void&gt;(QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG));
}
--ip;
}
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(320, ip &gt; 0);
QF_CRIT_EXIT();
ip = hsm_tran(path, qsId); // take the tran.
#ifdef Q_SPY
if (r == Q_RET_TRAN_HIST) {
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_TRAN_HIST, qsId)
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(t); // the source of the transition
QS_FUN_PRE_(path[0]); // the target of the tran. to history
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();
}
#endif // Q_SPY
// execute state entry actions in the desired order...
// note: ip is the fixed upper loop bound
for (; ip &gt;= 0; --ip) {
// enter path[ip]
if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG)
== Q_RET_HANDLED)
{
QS_STATE_ENTRY_(path[ip], qsId);
}
}
t = path[0]; // stick the target into register
m_temp.fun = t; // update the next state
// drill into the target hierarchy...
while (QHSM_RESERVED_EVT_(t, Q_INIT_SIG) == Q_RET_TRAN) {
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId)
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(t); // the source (pseudo)state
QS_FUN_PRE_(m_temp.fun); // the target of the tran.
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();
ip = 0;
path[0] = m_temp.fun;
// find superstate
static_cast&lt;void&gt;(QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
// note: ip is the fixed upper loop bound
while ((m_temp.fun != t) &amp;&amp; (ip &lt; (MAX_NEST_DEPTH_ - 1))) {
++ip;
path[ip] = m_temp.fun;
// find superstate
static_cast&lt;void&gt;(
QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
}
QF_CRIT_ENTRY();
// too many state nesting levels or &quot;malformed&quot; HSM
Q_ENSURE_INCRIT(330, ip &lt; MAX_NEST_DEPTH_);
QF_CRIT_EXIT();
m_temp.fun = path[0];
// retrace the entry path in reverse (correct) order...
// note: ip is the fixed upper loop bound
do {
// enter path[ip]
if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG)
== Q_RET_HANDLED)
{
QS_STATE_ENTRY_(path[ip], qsId);
}
--ip;
} while (ip &gt;= 0);
t = path[0]; // current state becomes the new source
}
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_TRAN, qsId)
QS_TIME_PRE_(); // time stamp
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(s); // the source of the tran.
QS_FUN_PRE_(t); // the new active state
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();
}
#ifdef Q_SPY
else if (r == Q_RET_HANDLED) {
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_INTERN_TRAN, qsId)
QS_TIME_PRE_(); // time stamp
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(s); // the source state
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();
}
else {
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_IGNORED, qsId)
QS_TIME_PRE_(); // time stamp
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(m_state.fun); // the current state
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();
}
#endif // Q_SPY
m_state.fun = t; // change the current active state
#ifndef Q_UNSAFE
m_temp.uint = ~m_state.uint;
#endif</code>
</operation>
<!--${QEP::QHsm::isIn}-->
<operation name="isIn" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept override</specifiers>
<!--${QEP::QHsm::isIn::state}-->
<parameter name="state" type="QStateHandler const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_INVARIANT_INCRIT(602, m_state.uint
== static_cast&lt;std::uintptr_t&gt;(~m_temp.uint));
QF_CRIT_EXIT();
bool inState = false; // assume that this HSM is not in 'state'
// scan the state hierarchy bottom-up
QStateHandler s = m_state.fun;
std::int_fast8_t lbound = MAX_NEST_DEPTH_ + 1; // fixed upper loop bound
QState r = Q_RET_SUPER;
for (; (r != Q_RET_IGNORED) &amp;&amp; (lbound &gt; 0); --lbound) {
if (s == state) { // do the states match?
inState = true; // 'true' means that match found
break; // break out of the for-loop
}
else {
r = QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG);
s = m_temp.fun;
}
}
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(690, lbound &gt; 0);
QF_CRIT_EXIT();
#ifndef Q_UNSAFE
m_temp.uint = ~m_state.uint;
#endif
return inState; // return the status</code>
</operation>
<!--${QEP::QHsm::childState}-->
<operation name="childState" type="QStateHandler" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QEP::QHsm::childState::parent}-->
<parameter name="parent" type="QStateHandler const"/>
<code>QStateHandler child = m_state.fun; // start with current state
bool isFound = false; // start with the child not found
// establish stable state configuration
m_temp.fun = child;
QState r;
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
do {
// is this the parent of the current child?
if (m_temp.fun == parent) {
isFound = true; // child is found
r = Q_RET_IGNORED; // break out of the loop
}
else {
child = m_temp.fun;
r = QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG);
}
--lbound;
} while ((r != Q_RET_IGNORED) // QHsm::top() state not reached
&amp;&amp; (lbound &gt; 0));
#ifndef Q_UNSAFE
m_temp.uint = ~m_state.uint;
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
// NOTE: the following postcondition can only succeed when
// (lbound &gt; 0), so no extra check is necessary.
Q_ENSURE_INCRIT(890, isFound);
QF_CRIT_EXIT();
return child;</code>
</operation>
<!--${QEP::QHsm::getStateHandler}-->
<operation name="getStateHandler?def Q_SPY" type="QStateHandler" visibility="0x00" properties="0x06">
<specifiers>noexcept override</specifiers>
<code>return m_state.fun;</code>
</operation>
<!--${QEP::QHsm::hsm_tran}-->
<operation name="hsm_tran" type="std::int_fast8_t" visibility="0x02" properties="0x00">
<!--${QEP::QHsm::hsm_tran::(&path)[MAX_NEST_DEPTH_]}-->
<parameter name="(&amp;path)[MAX_NEST_DEPTH_]" type="QStateHandler"/>
<!--${QEP::QHsm::hsm_tran::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(qsId);
#endif
std::int_fast8_t ip = -1; // tran. entry path index
QStateHandler t = path[0];
QStateHandler const s = path[2];
QF_CRIT_STAT
// (a) check source==target (tran. to self)...
if (s == t) {
// exit source s
if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) {
QS_STATE_EXIT_(s, qsId);
}
ip = 0; // enter the target
}
else {
// find superstate of target
static_cast&lt;void&gt;(QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG));
t = m_temp.fun;
// (b) check source==target-&gt;super...
if (s == t) {
ip = 0; // enter the target
}
else {
// find superstate of src
static_cast&lt;void&gt;(QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG));
// (c) check source-&gt;super==target-&gt;super...
if (m_temp.fun == t) {
// exit source s
if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) {
QS_STATE_EXIT_(s, qsId);
}
ip = 0; // enter the target
}
else {
// (d) check source-&gt;super==target...
if (m_temp.fun == path[0]) {
// exit source s
if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) {
QS_STATE_EXIT_(s, qsId);
}
}
else {
// (e) check rest of source==target-&gt;super-&gt;super..
// and store the entry path along the way
std::int_fast8_t iq = 0; // indicate that LCA was found
ip = 1; // enter target and its superstate
path[1] = t; // save the superstate of target
t = m_temp.fun; // save source-&gt;super
// find target-&gt;super-&gt;super...
// note: ip is the fixed upper loop bound
QState r = QHSM_RESERVED_EVT_(path[1], Q_EMPTY_SIG);
while ((r == Q_RET_SUPER)
&amp;&amp; (ip &lt; (MAX_NEST_DEPTH_ - 1)))
{
++ip;
path[ip] = m_temp.fun; // store the entry path
if (m_temp.fun == s) { // is it the source?
iq = 1; // indicate that the LCA found
--ip; // do not enter the source
r = Q_RET_HANDLED; // terminate the loop
}
else { // it is not the source, keep going up
r = QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG);
}
}
QF_CRIT_ENTRY();
// NOTE: The following postcondition succeeds only when
// ip &lt; QHSM_MAX_NEST_DEPTH, so no additional check is necessary
// too many state nesting levels or &quot;malformed&quot; HSM.
Q_ENSURE_INCRIT(510, r != Q_RET_SUPER);
QF_CRIT_EXIT();
// the LCA not found yet?
if (iq == 0) {
// exit source s
if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG)
== Q_RET_HANDLED)
{
QS_STATE_EXIT_(s, qsId);
}
// (f) check the rest of source-&gt;super
// == target-&gt;super-&gt;super...
iq = ip;
r = Q_RET_IGNORED; // indicate that the LCA NOT found
// note: iq is the fixed upper loop bound
do {
if (t == path[iq]) { // is this the LCA?
r = Q_RET_HANDLED; // indicate the LCA found
ip = iq - 1; // do not enter the LCA
iq = -1; // cause termination of the loop
}
else {
--iq; // try lower superstate of target
}
} while (iq &gt;= 0);
// the LCA not found yet?
if (r != Q_RET_HANDLED) {
// (g) check each source-&gt;super-&gt;...
// for each target-&gt;super...
r = Q_RET_IGNORED; // keep looping
std::int_fast8_t lbound = MAX_NEST_DEPTH_;
do {
// exit from t
if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG)
== Q_RET_HANDLED)
{
QS_STATE_EXIT_(t, qsId);
// find superstate of t
static_cast&lt;void&gt;(
QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG));
}
t = m_temp.fun; // set to super of t
iq = ip;
do {
// is this the LCA?
if (t == path[iq]) {
ip = iq - 1; // do not enter the LCA
iq = -1; // break out of inner loop
r = Q_RET_HANDLED; // break outer loop
}
else {
--iq;
}
} while (iq &gt;= 0);
--lbound;
} while ((r != Q_RET_HANDLED) &amp;&amp; (lbound &gt; 0));
QF_CRIT_ENTRY();
Q_ASSERT_INCRIT(530, lbound &gt; 0);
QF_CRIT_EXIT();
}
}
}
}
}
}
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(590, ip &lt; MAX_NEST_DEPTH_);
QF_CRIT_EXIT();
return ip;</code>
</operation>
</class>
<!--${QEP::QMsm}-->
<class name="QMsm" superclass="QEP::QAsm">
<documentation>Machine-generated State Machine</documentation>
<!--${QEP::QMsm::QMsm}-->
<operation name="QMsm" type="explicit" visibility="0x01" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QEP::QMsm::QMsm::initial}-->
<parameter name="initial" type="QStateHandler const"/>
<code> : QAsm()
m_state.obj = &amp;l_msm_top_s; // the current state (top)
m_temp.fun = initial; // the initial tran. handler</code>
</operation>
<!--${QEP::QMsm::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x04">
<specifiers>override</specifiers>
<!--${QEP::QMsm::init::e}-->
<parameter name="e" type="void const * const"/>
<!--${QEP::QMsm::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(qsId);
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(200, (m_temp.fun != nullptr)
&amp;&amp; (m_state.obj == &amp;l_msm_top_s));
QF_CRIT_EXIT();
// execute the top-most initial tran.
QState r = (*m_temp.fun)(this, Q_EVT_CAST(QEvt));
QF_CRIT_ENTRY();
// the top-most initial tran. must be taken
Q_ASSERT_INCRIT(210, r == Q_RET_TRAN_INIT);
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId)
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(m_state.obj-&gt;stateHandler); // source state
QS_FUN_PRE_(m_temp.tatbl-&gt;target-&gt;stateHandler); // target state
QS_END_PRE_()
QS_MEM_APP();
QF_CRIT_EXIT();
// set state to the last tran. target
m_state.obj = m_temp.tatbl-&gt;target;
// drill down into the state hierarchy with initial transitions...
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
do {
// execute the tran. table
r = execTatbl_(m_temp.tatbl, qsId);
--lbound;
} while ((r &gt;= Q_RET_TRAN_INIT) &amp;&amp; (lbound &gt; 0));
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(290, lbound &gt; 0);
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qsId)
QS_TIME_PRE_(); // time stamp
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(m_state.obj-&gt;stateHandler); // the new current state
QS_END_PRE_()
QS_MEM_APP();
QF_CRIT_EXIT();
#ifndef Q_UNSAFE
m_temp.uint = ~m_state.uint;
#endif</code>
</operation>
<!--${QEP::QMsm::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x06">
<specifiers>override</specifiers>
<!--${QEP::QMsm::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>this-&gt;init(nullptr, qsId);</code>
</operation>
<!--${QEP::QMsm::dispatch}-->
<operation name="dispatch" type="void" visibility="0x00" properties="0x04">
<specifiers>override</specifiers>
<!--${QEP::QMsm::dispatch::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QEP::QMsm::dispatch::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(qsId);
#endif
QMState const *s = m_state.obj; // store the current state
QMState const *t = s;
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_INVARIANT_INCRIT(300, (s != nullptr)
&amp;&amp; (m_state.uint == static_cast&lt;std::uintptr_t&gt;(~m_temp.uint)));
Q_INVARIANT_INCRIT(302, QEvt::verify_(e));
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId)
QS_TIME_PRE_(); // time stamp
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(s-&gt;stateHandler); // the current state handler
QS_END_PRE_()
QS_MEM_APP();
QF_CRIT_EXIT();
// scan the state hierarchy up to the top state...
QState r;
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
do {
r = (*t-&gt;stateHandler)(this, e); // call state handler function
// event handled? (the most frequent case)
if (r &gt;= Q_RET_HANDLED) {
break; // done scanning the state hierarchy
}
// event unhandled and passed to the superstate?
else if (r == Q_RET_SUPER) {
t = t-&gt;superstate; // advance to the superstate
}
// event unhandled and passed to a submachine superstate?
else if (r == Q_RET_SUPER_SUB) {
t = m_temp.obj; // current host state of the submachie
}
else { // event unhandled due to a guard?
QF_CRIT_ENTRY();
// event must be unhandled due to a guard evaluating to 'false'
Q_ASSERT_INCRIT(310, r == Q_RET_UNHANDLED);
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_UNHANDLED, qsId)
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(t-&gt;stateHandler); // the current state
QS_END_PRE_()
QS_MEM_APP();
QF_CRIT_EXIT();
t = t-&gt;superstate; // advance to the superstate
}
--lbound;
} while ((t != nullptr) &amp;&amp; (lbound &gt; 0));
QF_CRIT_ENTRY();
Q_ASSERT_INCRIT(310, lbound &gt; 0);
QF_CRIT_EXIT();
if (r &gt;= Q_RET_TRAN) { // any kind of tran. taken?
#ifdef Q_SPY
QMState const * const ts = t; // tran. source for QS tracing
QF_CRIT_ENTRY();
// the tran. source state must not be nullptr
Q_ASSERT_INCRIT(320, ts != nullptr);
QF_CRIT_EXIT();
#endif // Q_SPY
lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
do {
// save the tran-action table before it gets clobbered
QMTranActTable const * const tatbl = m_temp.tatbl;
QAsmAttr tmp; // temporary to save intermediate values
// was TRAN, TRAN_INIT, or TRAN_EP taken?
if (r &lt;= Q_RET_TRAN_EP) {
m_temp.obj = nullptr; // clear
exitToTranSource_(s, t, qsId);
r = execTatbl_(tatbl, qsId);
s = m_state.obj;
}
// was a tran. segment to history taken?
else if (r == Q_RET_TRAN_HIST) {
tmp.obj = m_state.obj; // save history
m_state.obj = s; // restore the original state
exitToTranSource_(s, t, qsId);
static_cast&lt;void&gt;(execTatbl_(tatbl, qsId));
r = enterHistory_(tmp.obj, qsId);
s = m_state.obj;
}
else {
QF_CRIT_ENTRY();
// must be tran. to exit point
Q_ASSERT_INCRIT(340, r == Q_RET_TRAN_XP);
QF_CRIT_EXIT();
tmp.act = m_state.act; // save XP action
m_state.obj = s; // restore the original state
r = (*tmp.act)(this); // execute the XP action
if (r == Q_RET_TRAN) { // XP -&gt; TRAN ?
#ifdef Q_SPY
tmp.tatbl = m_temp.tatbl; // save m_temp
#endif // Q_SPY
exitToTranSource_(s, t, qsId);
// take the tran-to-XP segment inside submachine
static_cast&lt;void&gt;(execTatbl_(tatbl, qsId));
s = m_state.obj;
#ifdef Q_SPY
m_temp.tatbl = tmp.tatbl; // restore m_temp
#endif // Q_SPY
}
else if (r == Q_RET_TRAN_HIST) { // XP -&gt; HIST ?
tmp.obj = m_state.obj; // save the history
m_state.obj = s; // restore the original state
#ifdef Q_SPY
s = m_temp.obj; // save m_temp
#endif // Q_SPY
exitToTranSource_(m_state.obj, t, qsId);
// take the tran-to-XP segment inside submachine
static_cast&lt;void&gt;(execTatbl_(tatbl, qsId));
#ifdef Q_SPY
m_temp.obj = s; // restore m_temp
#endif // Q_SPY
s = m_state.obj;
m_state.obj = tmp.obj; // restore the history
}
else {
QF_CRIT_ENTRY();
// TRAN_XP must NOT be followed by any other tran type
Q_ASSERT_INCRIT(330, r &lt; Q_RET_TRAN);
QF_CRIT_EXIT();
}
}
t = s; // set target to the current state
--lbound;
} while ((r &gt;= Q_RET_TRAN) &amp;&amp; (lbound &gt; 0));
QF_CRIT_ENTRY();
Q_ASSERT_INCRIT(320, lbound &gt; 0);
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_TRAN, qsId)
QS_TIME_PRE_(); // time stamp
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(ts-&gt;stateHandler); // the tran. source
QS_FUN_PRE_(s-&gt;stateHandler); // the new active state
QS_END_PRE_()
QS_MEM_APP();
QF_CRIT_EXIT();
}
#ifdef Q_SPY
// was the event handled?
else if (r == Q_RET_HANDLED) {
QF_CRIT_ENTRY();
// internal tran. source can't be nullptr
Q_ASSERT_INCRIT(340, t != nullptr);
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_INTERN_TRAN, qsId)
QS_TIME_PRE_(); // time stamp
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(t-&gt;stateHandler); // the source state
QS_END_PRE_()
QS_MEM_APP();
QF_CRIT_EXIT();
}
// event bubbled to the 'top' state?
else if (t == nullptr) {
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_IGNORED, qsId)
QS_TIME_PRE_(); // time stamp
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(s-&gt;stateHandler); // the current state
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();
}
#endif // Q_SPY
else {
// empty
}
#ifndef Q_UNSAFE
m_temp.uint = ~m_state.uint;
#endif</code>
</operation>
<!--${QEP::QMsm::getStateHandler}-->
<operation name="getStateHandler?def Q_SPY" type="QStateHandler" visibility="0x00" properties="0x02">
<specifiers>noexcept override</specifiers>
<code>return m_state.obj-&gt;stateHandler;</code>
</operation>
<!--${QEP::QMsm::isIn}-->
<operation name="isIn" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept override</specifiers>
<!--${QEP::QMsm::isIn::state}-->
<parameter name="state" type="QStateHandler const"/>
<code>bool inState = false; // assume that this SM is not in 'state'
QMState const *s = m_state.obj;
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
for (; (s != nullptr) &amp;&amp; (lbound &gt; 0); --lbound) {
if (s-&gt;stateHandler == state) { // match found?
inState = true;
break;
}
else {
s = s-&gt;superstate; // advance to the superstate
}
}
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(490, lbound &gt; 0);
QF_CRIT_EXIT();
return inState;</code>
</operation>
<!--${QEP::QMsm::isInState}-->
<operation name="isInState" type="bool" visibility="0x00" properties="0x00">
<specifiers>const noexcept</specifiers>
<documentation>//! @deprecated instead use: QMsm::isIn()</documentation>
<!--${QEP::QMsm::isInState::stateObj}-->
<parameter name="stateObj" type="QMState const * const"/>
<code>bool inState = false; // assume that this SM is not in 'state'
QMState const *s = m_state.obj;
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
for (; (s != nullptr) &amp;&amp; (lbound &gt; 0); --lbound) {
if (s == stateObj) { // match found?
inState = true;
break;
}
else {
s = s-&gt;superstate; // advance to the superstate
}
}
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(590, lbound &gt; 0);
QF_CRIT_EXIT();
return inState;</code>
</operation>
<!--${QEP::QMsm::childStateObj}-->
<operation name="childStateObj" type="QMState const *" visibility="0x00" properties="0x00">
<specifiers>const noexcept</specifiers>
<!--${QEP::QMsm::childStateObj::parent}-->
<parameter name="parent" type="QMState const * const"/>
<code>QMState const *child = m_state.obj;
bool isFound = false; // start with the child not found
QMState const *s;
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
for (s = m_state.obj;
(s != nullptr) &amp;&amp; (lbound &gt; 0);
s = s-&gt;superstate)
{
if (s == parent) {
isFound = true; // child is found
break;
}
else {
child = s;
}
--lbound;
}
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_ASSERT_INCRIT(610, lbound &gt; 0);
QF_CRIT_EXIT();
if (!isFound) { // still not found?
lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
for (s = m_temp.obj;
(s != nullptr) &amp;&amp; (lbound &gt; 0);
s = s-&gt;superstate)
{
if (s == parent) {
isFound = true; // child is found
break;
}
else {
child = s;
}
--lbound;
}
}
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(690, isFound &amp;&amp; (lbound &gt; 0));
QF_CRIT_EXIT();
return child; // return the child</code>
</operation>
<!--${QEP::QMsm::execTatbl_}-->
<operation name="execTatbl_" type="QState" visibility="0x02" properties="0x00">
<!--${QEP::QMsm::execTatbl_::tatbl}-->
<parameter name="tatbl" type="QMTranActTable const * const"/>
<!--${QEP::QMsm::execTatbl_::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(qsId);
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
// precondition:
// - the tran-action table pointer must not be NULL
Q_REQUIRE_INCRIT(700, tatbl != nullptr);
QF_CRIT_EXIT();
QState r = Q_RET_NULL;
std::int_fast8_t lbound = MAX_TRAN_LENGTH_; // fixed upper loop bound
QActionHandler const *a = &amp;tatbl-&gt;act[0];
for (; (*a != nullptr) &amp;&amp; (lbound &gt; 0); ++a) {
r = (*(*a))(this); // call the action through the 'a' pointer
#ifdef Q_SPY
QS_CRIT_ENTRY();
QS_MEM_SYS();
if (r == Q_RET_ENTRY) {
QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, qsId)
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(m_temp.obj-&gt;stateHandler); // entered state
QS_END_PRE_()
}
else if (r == Q_RET_EXIT) {
QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, qsId)
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(m_temp.obj-&gt;stateHandler); // exited state
QS_END_PRE_()
}
else if (r == Q_RET_TRAN_INIT) {
QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId)
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(tatbl-&gt;target-&gt;stateHandler); // source
QS_FUN_PRE_(m_temp.tatbl-&gt;target-&gt;stateHandler); // target
QS_END_PRE_()
}
else if (r == Q_RET_TRAN_EP) {
QS_BEGIN_PRE_(QS_QEP_TRAN_EP, qsId)
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(tatbl-&gt;target-&gt;stateHandler); // source
QS_FUN_PRE_(m_temp.tatbl-&gt;target-&gt;stateHandler); // target
QS_END_PRE_()
}
else if (r == Q_RET_TRAN_XP) {
QS_BEGIN_PRE_(QS_QEP_TRAN_XP, qsId)
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(tatbl-&gt;target-&gt;stateHandler); // source
QS_FUN_PRE_(m_temp.tatbl-&gt;target-&gt;stateHandler); // target
QS_END_PRE_()
}
else {
// empty
}
QS_MEM_APP();
QS_CRIT_EXIT();
#endif // Q_SPY
--lbound;
}
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(790, *a == nullptr);
QF_CRIT_EXIT();
m_state.obj = (r &gt;= Q_RET_TRAN)
? m_temp.tatbl-&gt;target
: tatbl-&gt;target;
return r;</code>
</operation>
<!--${QEP::QMsm::exitToTranSource_}-->
<operation name="exitToTranSource_" type="void" visibility="0x02" properties="0x00">
<!--${QEP::QMsm::exitToTranSource~::cs}-->
<parameter name="cs" type="QMState const * const"/>
<!--${QEP::QMsm::exitToTranSource~::ts}-->
<parameter name="ts" type="QMState const * const"/>
<!--${QEP::QMsm::exitToTranSource~::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(qsId);
#endif
QF_CRIT_STAT
// exit states from the current state to the tran. source state
QMState const *s = cs;
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
for (; (s != ts) &amp;&amp; (lbound &gt; 0); --lbound) {
// exit action provided in state 's'?
if (s-&gt;exitAction != nullptr) {
// execute the exit action
static_cast&lt;void&gt;((*s-&gt;exitAction)(this));
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, qsId)
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(s-&gt;stateHandler); // the exited state handler
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();
}
s = s-&gt;superstate; // advance to the superstate
if (s == nullptr) { // reached the top of a submachine?
s = m_temp.obj; // the superstate from QM_SM_EXIT()
QF_CRIT_ENTRY();
Q_ASSERT_INCRIT(810, s != nullptr); // must be valid
QF_CRIT_EXIT();
}
}
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(890, lbound &gt; 0);
QF_CRIT_EXIT();</code>
</operation>
<!--${QEP::QMsm::enterHistory_}-->
<operation name="enterHistory_" type="QState" visibility="0x02" properties="0x00">
<!--${QEP::QMsm::enterHistory_::hist}-->
<parameter name="hist" type="QMState const * const"/>
<!--${QEP::QMsm::enterHistory_::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(qsId);
#endif
QMState const *s = hist;
QMState const *ts = m_state.obj; // tran. source
QMState const *epath[MAX_ENTRY_DEPTH_];
QF_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_TRAN_HIST, qsId)
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(ts-&gt;stateHandler); // source state handler
QS_FUN_PRE_(hist-&gt;stateHandler); // target state handler
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();
std::int_fast8_t i = 0; // tran. entry path index
while ((s != ts) &amp;&amp; (i &lt; MAX_ENTRY_DEPTH_)) {
if (s-&gt;entryAction != nullptr) {
epath[i] = s;
++i;
}
s = s-&gt;superstate;
if (s == nullptr) {
ts = s; // force exit from the for-loop
}
}
QF_CRIT_ENTRY();
Q_ASSERT_INCRIT(910, s == ts);
QF_CRIT_EXIT();
// retrace the entry path in reverse (desired) order...
while (i &gt; 0) {
--i;
(*epath[i]-&gt;entryAction)(this); // run entry action in epath[i]
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, qsId)
QS_OBJ_PRE_(this);
QS_FUN_PRE_(epath[i]-&gt;stateHandler); // entered state handler
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();
}
m_state.obj = hist; // set current state to the tran. target
// initial tran. present?
QState r;
if (hist-&gt;initAction != nullptr) {
r = (*hist-&gt;initAction)(this); // execute the tran. action
}
else {
r = Q_RET_NULL;
}
return r;</code>
</operation>
<!--${QEP::QMsm::topQMState}-->
<operation name="topQMState" type="QMState const *" visibility="0x00" properties="0x00">
<specifiers>const noexcept</specifiers>
<code>return &amp;l_msm_top_s;</code>
</operation>
</class>
</package>
<!--${QEP-macros}-->
<package name="QEP-macros" stereotype="0x02">
<!--${QEP-macros::Q_STATE_DECL}-->
<operation name="Q_STATE_DECL" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::Q_STATE_DECL::state_}-->
<parameter name="state_" type="&lt;state name&gt;"/>
<code>\
QP::QState state_ ## _h(QP::QEvt const * const e); \
static QP::QState state_(void * const me, QP::QEvt const * const e)</code>
</operation>
<!--${QEP-macros::Q_STATE_DEF}-->
<operation name="Q_STATE_DEF" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::Q_STATE_DEF::subclass_}-->
<parameter name="subclass_" type="&lt;QHsm subclass&gt;"/>
<!--${QEP-macros::Q_STATE_DEF::state_}-->
<parameter name="state_" type="&lt;state name&gt;"/>
<code>\
QP::QState subclass_::state_(void * const me, QP::QEvt const * const e) { \
return static_cast&lt;subclass_ *&gt;(me)-&gt;state_ ## _h(e); } \
QP::QState subclass_::state_ ## _h(QP::QEvt const * const e)</code>
</operation>
<!--${QEP-macros::Q_HANDLED}-->
<operation name="Q_HANDLED" type="" visibility="0x03" properties="0x00">
<code>(Q_RET_HANDLED)</code>
</operation>
<!--${QEP-macros::Q_UNHANDLED}-->
<operation name="Q_UNHANDLED" type="" visibility="0x03" properties="0x00">
<code>(Q_RET_UNHANDLED)</code>
</operation>
<!--${QEP-macros::Q_EVT_CAST}-->
<operation name="Q_EVT_CAST" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::Q_EVT_CAST::subclass_}-->
<parameter name="subclass_" type="&lt;QEvt subclass&gt;"/>
<code>(static_cast&lt;subclass_ const *&gt;(e))</code>
</operation>
<!--${QEP-macros::Q_STATE_CAST}-->
<operation name="Q_STATE_CAST" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::Q_STATE_CAST::handler_}-->
<parameter name="handler_" type="&lt;state handler&gt;"/>
<code>\
(reinterpret_cast&lt;QP::QStateHandler&gt;(handler_))</code>
</operation>
<!--${QEP-macros::QM_STATE_DECL}-->
<operation name="QM_STATE_DECL" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::QM_STATE_DECL::state_}-->
<parameter name="state_" type="&lt;state name&gt;"/>
<code>\
QP::QState state_ ## _h(QP::QEvt const * const e); \
static QP::QState state_(void * const me, QP::QEvt const * const e); \
static QP::QMState const state_ ## _s</code>
</operation>
<!--${QEP-macros::QM_SM_STATE_DECL}-->
<operation name="QM_SM_STATE_DECL" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::QM_SM_STATE_DECL::subm_}-->
<parameter name="subm_" type="&lt;submachine name&gt;"/>
<!--${QEP-macros::QM_SM_STATE_DECL::state_}-->
<parameter name="state_" type="&lt;state name&gt;"/>
<code>\
QP::QState state_ ## _h(QP::QEvt const * const e);\
static QP::QState state_(void * const me, QP::QEvt const * const e); \
static SM_ ## subm_ const state_ ## _s</code>
</operation>
<!--${QEP-macros::QM_ACTION_DECL}-->
<operation name="QM_ACTION_DECL" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::QM_ACTION_DECL::action_}-->
<parameter name="action_" type="&lt;predefined&gt;"/>
<code>\
QP::QState action_ ## _h(); \
static QP::QState action_(void * const me)</code>
</operation>
<!--${QEP-macros::QM_STATE_DEF}-->
<operation name="QM_STATE_DEF" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::QM_STATE_DEF::subclass_}-->
<parameter name="subclass_" type="&lt;QMsm subclass&gt;"/>
<!--${QEP-macros::QM_STATE_DEF::state_}-->
<parameter name="state_" type="&lt;state name&gt;"/>
<code>\
QP::QState subclass_::state_(void * const me, QP::QEvt const * const e) {\
return static_cast&lt;subclass_ *&gt;(me)-&gt;state_ ## _h(e); } \
QP::QState subclass_::state_ ## _h(QP::QEvt const * const e)</code>
</operation>
<!--${QEP-macros::QM_ACTION_DEF}-->
<operation name="QM_ACTION_DEF" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::QM_ACTION_DEF::subclass_}-->
<parameter name="subclass_" type="&lt;QMsm subclass&gt;"/>
<!--${QEP-macros::QM_ACTION_DEF::action_}-->
<parameter name="action_" type="&lt;predefined&gt;"/>
<code> \
QP::QState subclass_::action_(void * const me) { \
return static_cast&lt;subclass_ *&gt;(me)-&gt;action_ ## _h(); } \
QP::QState subclass_::action_ ## _h()</code>
</operation>
<!--${QEP-macros::QM_HANDLED}-->
<operation name="QM_HANDLED" type="" visibility="0x03" properties="0x00">
<code>(Q_RET_HANDLED)</code>
</operation>
<!--${QEP-macros::QM_UNHANDLED}-->
<operation name="QM_UNHANDLED" type="" visibility="0x03" properties="0x00">
<code>(Q_RET_HANDLED)</code>
</operation>
<!--${QEP-macros::QM_SUPER}-->
<operation name="QM_SUPER" type="" visibility="0x03" properties="0x00">
<code>(Q_RET_SUPER)</code>
</operation>
<!--${QEP-macros::QM_STATE_NULL}-->
<attribute name="QM_STATE_NULL" type="&lt;action handler&gt;" visibility="0x03" properties="0x00">
<code>(nullptr)</code>
</attribute>
<!--${QEP-macros::Q_ACTION_NULL}-->
<attribute name="Q_ACTION_NULL" type="&lt;action handler&gt;" visibility="0x03" properties="0x00">
<code>(nullptr)</code>
</attribute>
<!--${QEP-macros::Q_UNUSED_PAR}-->
<operation name="Q_UNUSED_PAR" type="&lt;param type&gt;" visibility="0x03" properties="0x00">
<!--${QEP-macros::Q_UNUSED_PAR::par_}-->
<parameter name="par_" type="&lt;param type&gt;"/>
<code>(static_cast&lt;void&gt;(par_))</code>
</operation>
<!--${QEP-macros::Q_DIM}-->
<operation name="Q_DIM" type="unsigned" visibility="0x03" properties="0x00">
<!--${QEP-macros::Q_DIM::array_}-->
<parameter name="array_" type="1-dimensional array"/>
<code>(sizeof(array_) / sizeof((array_)[0U]))</code>
</operation>
<!--${QEP-macros::Q_UINT2PTR_CAST}-->
<operation name="Q_UINT2PTR_CAST" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::Q_UINT2PTR_CAST::type_}-->
<parameter name="type_" type=""/>
<!--${QEP-macros::Q_UINT2PTR_CAST::uint_}-->
<parameter name="uint_" type=""/>
<code>(reinterpret_cast&lt;type_ *&gt;(uint_))</code>
</operation>
<!--${QEP-macros::INIT}-->
<operation name="INIT?def Q_SPY" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::INIT::qsId_}-->
<parameter name="qsId_" type="std::uint8_fast8_t"/>
<code>init((qsId_))</code>
</operation>
<!--${QEP-macros::INIT}-->
<operation name="INIT?ndef Q_SPY" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::INIT::dummy}-->
<parameter name="dummy" type="std::uint8_fast8_t"/>
<code>init(0U)</code>
</operation>
<!--${QEP-macros::DISPATCH}-->
<operation name="DISPATCH?def Q_SPY" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::DISPATCH::e_}-->
<parameter name="e_" type="QP::QEvt const *"/>
<!--${QEP-macros::DISPATCH::qsId_}-->
<parameter name="qsId_" type="std::uint8_fast8_t"/>
<code>dispatch((e_), (qsId_))</code>
</operation>
<!--${QEP-macros::DISPATCH}-->
<operation name="DISPATCH?ndef Q_SPY" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::DISPATCH::e_}-->
<parameter name="e_" type="QP::QEvt const *"/>
<!--${QEP-macros::DISPATCH::dummy}-->
<parameter name="dummy" type="std::uint8_fast8_t"/>
<code>dispatch((e_), 0U)</code>
</operation>
</package>
<!--${QF}-->
<package name="QF" stereotype="0x05" namespace="QP::">
<!--${QF::types}-->
<package name="types" stereotype="0x02">
<!--${QF::types::QPrioSpec}-->
<attribute name="QPrioSpec" type="using" visibility="0x04" properties="0x00">
<code>= std::uint16_t;</code>
</attribute>
<!--${QF::types::QTimeEvtCtr}-->
<attribute name="QTimeEvtCtr? (QF_TIMEEVT_CTR_SIZE == 1U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint8_t;</code>
</attribute>
<!--${QF::types::QTimeEvtCtr}-->
<attribute name="QTimeEvtCtr? (QF_TIMEEVT_CTR_SIZE == 2U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint16_t;</code>
</attribute>
<!--${QF::types::QTimeEvtCtr}-->
<attribute name="QTimeEvtCtr? (QF_TIMEEVT_CTR_SIZE == 4U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint32_t;</code>
</attribute>
<!--${QF::types::QPSetBits}-->
<attribute name="QPSetBits? (QF_MAX_ACTIVE &lt;= 8U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint8_t;</code>
</attribute>
<!--${QF::types::QPSetBits}-->
<attribute name="QPSetBits? (8U &lt; QF_MAX_ACTIVE) &amp;&amp; (QF_MAX_ACTIVE &lt;= 16U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint16_t;</code>
</attribute>
<!--${QF::types::QPSetBits}-->
<attribute name="QPSetBits? (16 &lt; QF_MAX_ACTIVE)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint32_t;</code>
</attribute>
<!--${QF::types::QF_LOG2}-->
<operation name="QF_LOG2?ndef QF_LOG2" type="std::uint_fast8_t" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::types::QF_LOG2::x}-->
<parameter name="x" type="QP::QPSetBits"/>
<code>static std::uint8_t const log2LUT[16] = {
0U, 1U, 2U, 2U, 3U, 3U, 3U, 3U,
4U, 4U, 4U, 4U, 4U, 4U, 4U, 4U
};
std::uint_fast8_t n = 0U;
QP::QPSetBits t;
#if (QF_MAX_ACTIVE &gt; 16U)
t = static_cast&lt;QP::QPSetBits&gt;(x &gt;&gt; 16U);
if (t != 0U) {
n += 16U;
x = t;
}
#endif
#if (QF_MAX_ACTIVE &gt; 8U)
t = (x &gt;&gt; 8U);
if (t != 0U) {
n += 8U;
x = t;
}
#endif
t = (x &gt;&gt; 4U);
if (t != 0U) {
n += 4U;
x = t;
}
return n + log2LUT[x];</code>
</operation>
<!--${QF::types::QPSet}-->
<class name="QPSet">
<!--${QF::types::QPSet::m_bits[((QF_MAX_ACTIVE + (8U*siz~}-->
<attribute name="m_bits[((QF_MAX_ACTIVE + (8U*sizeof(QPSetBits))) - 1U)/(8U*sizeof(QPSetBits))]" type="QPSetBits" visibility="0x02" properties="0x00"/>
<!--${QF::types::QPSet::setEmpty}-->
<operation name="setEmpty" type="void" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<code>m_bits[0] = 0U;
#if (QF_MAX_ACTIVE &gt; 32)
m_bits[1] = 0U;
#endif</code>
</operation>
<!--${QF::types::QPSet::isEmpty}-->
<operation name="isEmpty" type="bool" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>#if (QF_MAX_ACTIVE &lt;= 32U)
return (m_bits[0] == 0U);
#else
return (m_bits[0] == 0U) ? (m_bits[1] == 0U) : false;
#endif</code>
</operation>
<!--${QF::types::QPSet::notEmpty}-->
<operation name="notEmpty" type="bool" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>#if (QF_MAX_ACTIVE &lt;= 32U)
return (m_bits[0] != 0U);
#else
return (m_bits[0] != 0U) ? true : (m_bits[1] != 0U);
#endif</code>
</operation>
<!--${QF::types::QPSet::hasElement}-->
<operation name="hasElement" type="bool" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<!--${QF::types::QPSet::hasElement::n}-->
<parameter name="n" type="std::uint_fast8_t const"/>
<code>#if (QF_MAX_ACTIVE &lt;= 32U)
return (m_bits[0] &amp; (static_cast&lt;QPSetBits&gt;(1U) &lt;&lt; (n - 1U))) != 0U;
#else
return (n &lt;= 32U)
? ((m_bits[0] &amp; (static_cast&lt;QPSetBits&gt;(1U) &lt;&lt; (n - 1U))) != 0U)
: ((m_bits[1] &amp; (static_cast&lt;QPSetBits&gt;(1U) &lt;&lt; (n - 33U))) != 0U);
#endif</code>
</operation>
<!--${QF::types::QPSet::insert}-->
<operation name="insert" type="void" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QF::types::QPSet::insert::n}-->
<parameter name="n" type="std::uint_fast8_t const"/>
<code>#if (QF_MAX_ACTIVE &lt;= 32U)
m_bits[0] = (m_bits[0] | (static_cast&lt;QPSetBits&gt;(1U) &lt;&lt; (n - 1U)));
#else
if (n &lt;= 32U) {
m_bits[0] = (m_bits[0] | (static_cast&lt;QPSetBits&gt;(1U) &lt;&lt; (n - 1U)));
}
else {
m_bits[1] = (m_bits[1] | (static_cast&lt;QPSetBits&gt;(1U) &lt;&lt; (n - 33U)));
}
#endif</code>
</operation>
<!--${QF::types::QPSet::remove}-->
<operation name="remove" type="void" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QF::types::QPSet::remove::n}-->
<parameter name="n" type="std::uint_fast8_t const"/>
<code>#if (QF_MAX_ACTIVE &lt;= 32U)
m_bits[0] = (m_bits[0] &amp; static_cast&lt;QPSetBits&gt;(~(1U &lt;&lt; (n - 1U))));
#else
if (n &lt;= 32U) {
(m_bits[0] = (m_bits[0] &amp; ~(static_cast&lt;QPSetBits&gt;(1U) &lt;&lt; (n - 1U))));
}
else {
(m_bits[1] = (m_bits[1] &amp; ~(static_cast&lt;QPSetBits&gt;(1U) &lt;&lt; (n - 33U))));
}
#endif</code>
</operation>
<!--${QF::types::QPSet::findMax}-->
<operation name="findMax" type="std::uint_fast8_t" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>#if (QF_MAX_ACTIVE &lt;= 32U)
return QF_LOG2(m_bits[0]);
#else
return (m_bits[1] != 0U)
? (QF_LOG2(m_bits[1]) + 32U)
: (QF_LOG2(m_bits[0]));
#endif</code>
</operation>
<!--${QF::types::QPSet::update_}-->
<operation name="update_?ndef Q_UNSAFE" type="void" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<!--${QF::types::QPSet::update_::dis}-->
<parameter name="dis" type="QPSet * const"/>
<code>dis-&gt;m_bits[0] = ~m_bits[0];
#if (QF_MAX_ACTIVE &gt; 32U)
dis-&gt;m_bits[1] = ~m_bits[1];
#endif</code>
</operation>
<!--${QF::types::QPSet::verify_}-->
<operation name="verify_?ndef Q_UNSAFE" type="bool" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<!--${QF::types::QPSet::verify_::dis}-->
<parameter name="dis" type="QPSet const * const"/>
<code>#if (QF_MAX_ACTIVE &lt;= 32U)
return m_bits[0] == static_cast&lt;QPSetBits&gt;(~dis-&gt;m_bits[0]);
#else
return (m_bits[0] == static_cast&lt;QPSetBits&gt;(~dis-&gt;m_bits[0]))
&amp;&amp; (m_bits[1] == static_cast&lt;QPSetBits&gt;(~dis-&gt;m_bits[1]));
#endif</code>
</operation>
</class>
<!--${QF::types::QSubscrList}-->
<class name="QSubscrList">
<!--${QF::types::QSubscrList::m_set}-->
<attribute name="m_set" type="QPSet" visibility="0x02" properties="0x00"/>
<!--${QF::types::QSubscrList::m_set_dis}-->
<attribute name="m_set_dis?ndef Q_UNSAFE" type="QPSet" visibility="0x02" properties="0x00"/>
<!--${QF::types::QSubscrList::QActive}-->
<attribute name="QActive" type="friend class" visibility="0x02" properties="0x00">
<documentation>// friends...</documentation>
</attribute>
</class>
<!--${QF::types::QEQueue}-->
<attribute name="QEQueue" type="class" visibility="0x04" properties="0x00"/>
</package>
<!--${QF::QActive}-->
<class name="QActive" superclass="QEP::QAsm">
<!--${QF::QActive::m_prio}-->
<attribute name="m_prio" type="std::uint8_t" visibility="0x01" properties="0x00"/>
<!--${QF::QActive::m_pthre}-->
<attribute name="m_pthre" type="std::uint8_t" visibility="0x01" properties="0x00"/>
<!--${QF::QActive::m_thread}-->
<attribute name="m_thread?def QACTIVE_THREAD_TYPE" type="QACTIVE_THREAD_TYPE" visibility="0x01" properties="0x00"/>
<!--${QF::QActive::m_osObject}-->
<attribute name="m_osObject?def QACTIVE_OS_OBJ_TYPE" type="QACTIVE_OS_OBJ_TYPE" visibility="0x01" properties="0x00"/>
<!--${QF::QActive::m_eQueue}-->
<attribute name="m_eQueue?def QACTIVE_EQUEUE_TYPE" type="QACTIVE_EQUEUE_TYPE" visibility="0x01" properties="0x00"/>
<!--${QF::QActive::m_prio_dis}-->
<attribute name="m_prio_dis?ndef Q_UNSAFE" type="std::uint8_t" visibility="0x00" properties="0x00"/>
<!--${QF::QActive::m_pthre_dis}-->
<attribute name="m_pthre_dis?ndef Q_UNSAFE" type="std::uint8_t" visibility="0x00" properties="0x00"/>
<!--${QF::QActive::registry_[QF_MAX_ACTIVE + 1U]}-->
<attribute name="registry_[QF_MAX_ACTIVE + 1U]" type="QActive *" visibility="0x00" properties="0x01"/>
<!--${QF::QActive::subscrList_}-->
<attribute name="subscrList_" type="QSubscrList *" visibility="0x00" properties="0x01"/>
<!--${QF::QActive::maxPubSignal_}-->
<attribute name="maxPubSignal_" type="enum_t" visibility="0x00" properties="0x01"/>
<!--${QF::QActive::QTimeEvt}-->
<attribute name="QTimeEvt" type="friend class" visibility="0x00" properties="0x00">
<documentation>// friends...</documentation>
</attribute>
<!--${QF::QActive::QTicker}-->
<attribute name="QTicker" type="friend class" visibility="0x00" properties="0x00"/>
<!--${QF::QActive::QXThread}-->
<attribute name="QXThread" type="friend class" visibility="0x00" properties="0x00"/>
<!--${QF::QActive::QXMutex}-->
<attribute name="QXMutex" type="friend class" visibility="0x00" properties="0x00"/>
<!--${QF::QActive::QXSemaphore}-->
<attribute name="QXSemaphore" type="friend class" visibility="0x00" properties="0x00"/>
<!--${QF::QActive::QActiveDummy}-->
<attribute name="QActiveDummy" type="friend class" visibility="0x00" properties="0x00"/>
<!--${QF::QActive::GuiQActive}-->
<attribute name="GuiQActive" type="friend class" visibility="0x00" properties="0x00"/>
<!--${QF::QActive::GuiQMActive}-->
<attribute name="GuiQMActive" type="friend class" visibility="0x00" properties="0x00"/>
<!--${QF::QActive::schedLock()}-->
<attribute name="schedLock()" type="friend void" visibility="0x00" properties="0x00"/>
<!--${QF::QActive::QActive}-->
<operation name="QActive" type="explicit" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QF::QActive::QActive::initial}-->
<parameter name="initial" type="QStateHandler const"/>
<code> : QAsm(),
m_prio(0U),
m_pthre(0U)
m_state.fun = Q_STATE_CAST(&amp;top);
m_temp.fun = initial;
#ifndef Q_UNSAFE
m_prio_dis = static_cast&lt;std::uint8_t&gt;(~m_prio);
m_pthre_dis = static_cast&lt;std::uint8_t&gt;(~m_pthre);
#endif</code>
</operation>
<!--${QF::QActive::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x02">
<specifiers>override</specifiers>
<!--${QF::QActive::init::e}-->
<parameter name="e" type="void const * const"/>
<!--${QF::QActive::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>reinterpret_cast&lt;QHsm *&gt;(this)-&gt;QHsm::init(e, qsId);</code>
</operation>
<!--${QF::QActive::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x06">
<specifiers>override</specifiers>
<!--${QF::QActive::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>this-&gt;init(nullptr, qsId);</code>
</operation>
<!--${QF::QActive::dispatch}-->
<operation name="dispatch" type="void" visibility="0x00" properties="0x02">
<specifiers>override</specifiers>
<!--${QF::QActive::dispatch::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QF::QActive::dispatch::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>reinterpret_cast&lt;QHsm *&gt;(this)-&gt;QHsm::dispatch(e, qsId);</code>
</operation>
<!--${QF::QActive::isIn}-->
<operation name="isIn" type="bool" visibility="0x00" properties="0x02">
<specifiers>noexcept override</specifiers>
<!--${QF::QActive::isIn::state}-->
<parameter name="state" type="QStateHandler const"/>
<code>return reinterpret_cast&lt;QHsm *&gt;(this)-&gt;QHsm::isIn(state);</code>
</operation>
<!--${QF::QActive::childState}-->
<operation name="childState" type="QStateHandler" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QF::QActive::childState::parent}-->
<parameter name="parent" type="QStateHandler const"/>
<code>return reinterpret_cast&lt;QHsm *&gt;(this)-&gt;QHsm::childState(parent);</code>
</operation>
<!--${QF::QActive::setAttr}-->
<operation name="setAttr" type="void" visibility="0x00" properties="0x00">
<!--${QF::QActive::setAttr::attr1}-->
<parameter name="attr1" type="std::uint32_t"/>
<!--${QF::QActive::setAttr::attr2 = nullptr}-->
<parameter name="attr2 = nullptr" type="void const *"/>
</operation>
<!--${QF::QActive::start}-->
<operation name="start" type="void" visibility="0x00" properties="0x00">
<!--${QF::QActive::start::prioSpec}-->
<parameter name="prioSpec" type="QPrioSpec const"/>
<!--${QF::QActive::start::qSto}-->
<parameter name="qSto" type="QEvt const * * const"/>
<!--${QF::QActive::start::qLen}-->
<parameter name="qLen" type="std::uint_fast16_t const"/>
<!--${QF::QActive::start::stkSto}-->
<parameter name="stkSto" type="void * const"/>
<!--${QF::QActive::start::stkSize}-->
<parameter name="stkSize" type="std::uint_fast16_t const"/>
<!--${QF::QActive::start::par}-->
<parameter name="par" type="void const * const"/>
</operation>
<!--${QF::QActive::start}-->
<operation name="start" type="void" visibility="0x00" properties="0x02">
<!--${QF::QActive::start::prioSpec}-->
<parameter name="prioSpec" type="QPrioSpec const"/>
<!--${QF::QActive::start::qSto}-->
<parameter name="qSto" type="QEvt const * * const"/>
<!--${QF::QActive::start::qLen}-->
<parameter name="qLen" type="std::uint_fast16_t const"/>
<!--${QF::QActive::start::stkSto}-->
<parameter name="stkSto" type="void * const"/>
<!--${QF::QActive::start::stkSize}-->
<parameter name="stkSize" type="std::uint_fast16_t const"/>
<code>this-&gt;start(prioSpec, qSto, qLen, stkSto, stkSize, nullptr);</code>
</operation>
<!--${QF::QActive::stop}-->
<operation name="stop?def QACTIVE_CAN_STOP" type="void" visibility="0x00" properties="0x00"/>
<!--${QF::QActive::register_}-->
<operation name="register_" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
if (m_pthre == 0U) { // preemption-threshold not defined?
m_pthre = m_prio; // apply the default
}
#ifndef Q_UNSAFE
Q_REQUIRE_INCRIT(100, (0U &lt; m_prio) &amp;&amp; (m_prio &lt;= QF_MAX_ACTIVE)
&amp;&amp; (registry_[m_prio] == nullptr)
&amp;&amp; (m_prio &lt;= m_pthre));
std::uint8_t prev_thre = m_pthre;
std::uint8_t next_thre = m_pthre;
std::uint_fast8_t p;
for (p = static_cast&lt;std::uint_fast8_t&gt;(m_prio) - 1U; p &gt; 0U; --p) {
if (registry_[p] != nullptr) {
prev_thre = registry_[p]-&gt;m_pthre;
break;
}
}
for (p = static_cast&lt;std::uint_fast8_t&gt;(m_prio) + 1U;
p &lt;= QF_MAX_ACTIVE; ++p)
{
if (registry_[p] != nullptr) {
next_thre = registry_[p]-&gt;m_pthre;
break;
}
}
Q_ASSERT_INCRIT(190, (prev_thre &lt;= m_pthre)
&amp;&amp; (m_pthre &lt;= next_thre));
m_prio_dis = static_cast&lt;std::uint8_t&gt;(~m_prio);
m_pthre_dis = static_cast&lt;std::uint8_t&gt;(~m_pthre);
#endif // Q_UNSAFE
// register the AO at the QF-prio.
registry_[m_prio] = this;
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QF::QActive::unregister_}-->
<operation name="unregister_" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>std::uint_fast8_t const p = static_cast&lt;std::uint_fast8_t&gt;(m_prio);
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(200, (0U &lt; p) &amp;&amp; (p &lt;= QF_MAX_ACTIVE)
&amp;&amp; (registry_[p] == this));
registry_[p] = nullptr; // free-up the priority level
m_state.fun = nullptr; // invalidate the state
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QF::QActive::post_}-->
<operation name="post_" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QActive::post_::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QF::QActive::post_::margin}-->
<parameter name="margin" type="std::uint_fast16_t const"/>
<!--${QF::QActive::post_::sender}-->
<parameter name="sender" type="void const * const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(sender);
#endif
#ifdef Q_UTEST // test?
#if Q_UTEST != 0 // testing QP-stub?
if (m_temp.fun == Q_STATE_CAST(0)) { // QActiveDummy?
return static_cast&lt;QActiveDummy *&gt;(this)-&gt;fakePost(e, margin, sender);
}
#endif
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
#ifndef Q_UNSAFE
std::uint8_t const pcopy = static_cast&lt;std::uint8_t&gt;(~m_prio_dis);
Q_INVARIANT_INCRIT(102, (QEvt::verify_(e)) &amp;&amp; (m_prio == pcopy));
#endif
QEQueueCtr nFree = m_eQueue.m_nFree; // get volatile into temporary
// test-probe#1 for faking queue overflow
QS_TEST_PROBE_DEF(&amp;QActive::post_)
QS_TEST_PROBE_ID(1,
nFree = 0U;
)
bool status;
if (margin == QF::NO_MARGIN) {
if (nFree &gt; 0U) {
status = true; // can post
}
else {
status = false; // cannot post
Q_ERROR_INCRIT(190); // must be able to post the event
}
}
else if (nFree &gt; static_cast&lt;QEQueueCtr&gt;(margin)) {
status = true; // can post
}
else {
status = false; // cannot post, but don't assert
}
// is it a mutable event?
if (e-&gt;getPoolNum_() != 0U) {
QEvt_refCtr_inc_(e); // increment the reference counter
}
if (status) { // can post the event?
--nFree; // one free entry just used up
m_eQueue.m_nFree = nFree; // update the original
if (m_eQueue.m_nMin &gt; nFree) {
m_eQueue.m_nMin = nFree; // update minimum so far
}
QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(sender); // the sender object
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_OBJ_PRE_(this); // this active object
QS_2U8_PRE_(e-&gt;getPoolNum_(), e-&gt;refCtr_); // poolNum &amp; refCtr
QS_EQC_PRE_(nFree); // # free entries
QS_EQC_PRE_(m_eQueue.m_nMin); // min # free entries
QS_END_PRE_()
#ifdef Q_UTEST
// callback to examine the posted event under the same conditions
// as producing the #QS_QF_ACTIVE_POST trace record, which are:
// the local filter for this AO ('m_prio') is set
if (QS_LOC_CHECK_(m_prio)) {
QS::onTestPost(sender, this, e, status);
}
#endif
if (m_eQueue.m_frontEvt == nullptr) { // empty queue?
m_eQueue.m_frontEvt = e; // deliver event directly
#ifdef QXK_HPP_
if (m_state.act == Q_ACTION_CAST(0)) { // eXtended thread?
QXTHREAD_EQUEUE_SIGNAL_(this); // signal the event queue
}
else {
QACTIVE_EQUEUE_SIGNAL_(this); // signal the event queue
}
#else
QACTIVE_EQUEUE_SIGNAL_(this); // signal the event queue
#endif
}
// queue is not empty, insert event into the ring-buffer
else {
// insert event into the ring buffer (FIFO)
m_eQueue.m_ring[m_eQueue.m_head] = e;
if (m_eQueue.m_head == 0U) { // need to wrap head?
m_eQueue.m_head = m_eQueue.m_end; // wrap around
}
// advance the head (counter clockwise)
m_eQueue.m_head = (m_eQueue.m_head - 1U);
}
QF_MEM_APP();
QF_CRIT_EXIT();
}
else { // cannot post the event
QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(sender); // the sender object
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_OBJ_PRE_(this); // this active object
QS_2U8_PRE_(e-&gt;getPoolNum_(), e-&gt;refCtr_); // poolNum &amp; refCtr
QS_EQC_PRE_(nFree); // # free entries
QS_EQC_PRE_(margin); // margin requested
QS_END_PRE_()
#ifdef Q_UTEST
// callback to examine the posted event under the same conditions
// as producing the #QS_QF_ACTIVE_POST trace record, which are:
// the local filter for this AO ('m_prio') is set
if (QS_LOC_CHECK_(m_prio)) {
QS::onTestPost(sender, this, e, status);
}
#endif
QF_MEM_APP();
QF_CRIT_EXIT();
#if (QF_MAX_EPOOL &gt; 0U)
QF::gc(e); // recycle the event to avoid a leak
#endif
}
return status;</code>
</operation>
<!--${QF::QActive::postLIFO}-->
<operation name="postLIFO" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QActive::postLIFO::e}-->
<parameter name="e" type="QEvt const * const"/>
<code>#ifdef Q_UTEST // test?
#if Q_UTEST != 0 // testing QP-stub?
if (m_temp.fun == Q_STATE_CAST(0)) { // QActiveDummy?
static_cast&lt;QActiveDummy *&gt;(this)-&gt;QActiveDummy::fakePostLIFO(e);
return;
}
#endif
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
#ifndef Q_UNSAFE
std::uint8_t const pcopy = static_cast&lt;std::uint8_t&gt;(~m_prio_dis);
Q_INVARIANT_INCRIT(202, (QEvt::verify_(e)) &amp;&amp; (m_prio == pcopy));
#endif
#ifdef QXK_HPP_
Q_REQUIRE_INCRIT(200, m_state.act != Q_ACTION_CAST(0));
#endif
QEQueueCtr nFree = m_eQueue.m_nFree; // get volatile into temporary
// test-probe#1 for faking queue overflow
QS_TEST_PROBE_DEF(&amp;QActive::postLIFO)
QS_TEST_PROBE_ID(1,
nFree = 0U;
)
Q_REQUIRE_INCRIT(201, nFree != 0U);
if (e-&gt;getPoolNum_() != 0U) { // is it a mutable event?
QEvt_refCtr_inc_(e); // increment the reference counter
}
--nFree; // one free entry just used up
m_eQueue.m_nFree = nFree; // update the original
if (m_eQueue.m_nMin &gt; nFree) {
m_eQueue.m_nMin = nFree; // update minimum so far
}
QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, m_prio)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(e-&gt;sig); // the signal of this event
QS_OBJ_PRE_(this); // this active object
QS_2U8_PRE_(e-&gt;getPoolNum_(), e-&gt;refCtr_); // poolNum &amp; refCtr
QS_EQC_PRE_(nFree); // # free entries
QS_EQC_PRE_(m_eQueue.m_nMin); // min # free entries
QS_END_PRE_()
#ifdef Q_UTEST
// callback to examine the posted event under the same conditions
// as producing the #QS_QF_ACTIVE_POST trace record, which are:
// the local filter for this AO ('m_prio') is set
if (QS_LOC_CHECK_(m_prio)) {
QS::onTestPost(nullptr, this, e, true);
}
#endif
QEvt const * const frontEvt = m_eQueue.m_frontEvt;
m_eQueue.m_frontEvt = e; // deliver the event directly to the front
if (frontEvt == nullptr) { // was the queue empty?
QACTIVE_EQUEUE_SIGNAL_(this); // signal the event queue
}
else { // queue was not empty, leave the event in the ring-buffer
m_eQueue.m_tail = (m_eQueue.m_tail + 1U);
if (m_eQueue.m_tail == m_eQueue.m_end) { // need to wrap the tail?
m_eQueue.m_tail = 0U; // wrap around
}
m_eQueue.m_ring[m_eQueue.m_tail] = frontEvt;
}
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QF::QActive::get_}-->
<operation name="get_" type="QEvt const *" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
QACTIVE_EQUEUE_WAIT_(this); // wait for event to arrive directly
// always remove evt from the front
QEvt const * const e = m_eQueue.m_frontEvt;
QEQueueCtr const nFree = m_eQueue.m_nFree + 1U; // get volatile into tmp
m_eQueue.m_nFree = nFree; // update the # free
if (nFree &lt;= m_eQueue.m_end) { // any events in the ring buffer?
// remove event from the tail
m_eQueue.m_frontEvt = m_eQueue.m_ring[m_eQueue.m_tail];
if (m_eQueue.m_tail == 0U) { // need to wrap the tail?
m_eQueue.m_tail = m_eQueue.m_end; // wrap around
}
m_eQueue.m_tail = (m_eQueue.m_tail - 1U);
QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, m_prio)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(e-&gt;sig); // the signal of this event
QS_OBJ_PRE_(this); // this active object
QS_2U8_PRE_(e-&gt;getPoolNum_(), e-&gt;refCtr_); // poolNum &amp; refCtr
QS_EQC_PRE_(nFree); // # free entries
QS_END_PRE_()
}
else {
m_eQueue.m_frontEvt = nullptr; // the queue becomes empty
// all entries in the queue must be free (+1 for fronEvt)
Q_ASSERT_INCRIT(310, nFree == (m_eQueue.m_end + 1U));
QS_BEGIN_PRE_(QS_QF_ACTIVE_GET_LAST, m_prio)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(e-&gt;sig); // the signal of this event
QS_OBJ_PRE_(this); // this active object
QS_2U8_PRE_(e-&gt;getPoolNum_(), e-&gt;refCtr_); // poolNum &amp; refCtr
QS_END_PRE_()
}
QF_MEM_APP();
QF_CRIT_EXIT();
return e;</code>
</operation>
<!--${QF::QActive::getQueueMin}-->
<operation name="getQueueMin" type="std::uint_fast16_t" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QActive::getQueueMin::prio}-->
<parameter name="prio" type="std::uint_fast8_t const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(400, (prio &lt;= QF_MAX_ACTIVE)
&amp;&amp; (QActive::registry_[prio] != nullptr));
std::uint_fast16_t const min = static_cast&lt;std::uint_fast16_t&gt;(
QActive::registry_[prio]-&gt;m_eQueue.getNMin());
QF_CRIT_EXIT();
return min;</code>
</operation>
<!--${QF::QActive::psInit}-->
<operation name="psInit" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QActive::psInit::subscrSto}-->
<parameter name="subscrSto" type="QSubscrList * const"/>
<!--${QF::QActive::psInit::maxSignal}-->
<parameter name="maxSignal" type="enum_t const"/>
<code>subscrList_ = subscrSto;
maxPubSignal_ = maxSignal;
// initialize the subscriber list
for (enum_t sig = 0; sig &lt; maxSignal; ++sig) {
subscrSto[sig].m_set.setEmpty();
#ifndef Q_UNSAFE
subscrSto[sig].m_set.update_(&amp;subscrSto[sig].m_set_dis);
#endif
}</code>
</operation>
<!--${QF::QActive::publish_}-->
<operation name="publish_" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QActive::publish_::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QF::QActive::publish_::sender}-->
<parameter name="sender" type="void const * const"/>
<!--${QF::QActive::publish_::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(sender);
Q_UNUSED_PAR(qsId);
#endif
QSignal const sig = e-&gt;sig;
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(200, sig &lt; static_cast&lt;QSignal&gt;(maxPubSignal_));
Q_INVARIANT_INCRIT(202,
subscrList_[sig].m_set.verify_(&amp;subscrList_[sig].m_set_dis));
QS_BEGIN_PRE_(QS_QF_PUBLISH, qsId)
QS_TIME_PRE_(); // the timestamp
QS_OBJ_PRE_(sender); // the sender object
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_2U8_PRE_(e-&gt;getPoolNum_(), e-&gt;refCtr_); // poolNum &amp; refCtr
QS_END_PRE_()
// is it a mutable event?
if (e-&gt;getPoolNum_() != 0U) {
// NOTE: The reference counter of a mutable event is incremented to
// prevent premature recycling of the event while the multicasting
// is still in progress. At the end of the function, the garbage
// collector step (QF::gc()) decrements the reference counter and
// recycles the event if the counter drops to zero. This covers the
// case when the event was published without any subscribers.
QEvt_refCtr_inc_(e);
}
// make a local, modifiable copy of the subscriber set
QPSet subscrSet = subscrList_[sig].m_set;
QF_MEM_APP();
QF_CRIT_EXIT();
if (subscrSet.notEmpty()) { // any subscribers?
// highest-prio subscriber
std::uint_fast8_t p = subscrSet.findMax();
QF_CRIT_ENTRY();
QF_MEM_SYS();
QActive *a = registry_[p];
// the AO must be registered with the framework
Q_ASSERT_INCRIT(210, a != nullptr);
QF_MEM_APP();
QF_CRIT_EXIT();
QF_SCHED_STAT_
QF_SCHED_LOCK_(p); // lock the scheduler up to AO's prio
std::uint_fast8_t lbound = QF_MAX_ACTIVE + 1U;
do { // loop over all subscribers
--lbound;
// POST() asserts internally if the queue overflows
a-&gt;POST(e, sender);
subscrSet.remove(p); // remove the handled subscriber
if (subscrSet.notEmpty()) { // still more subscribers?
p = subscrSet.findMax(); // highest-prio subscriber
QF_CRIT_ENTRY();
QF_MEM_SYS();
a = registry_[p];
// the AO must be registered with the framework
Q_ASSERT_INCRIT(220, a != nullptr);
QF_MEM_APP();
QF_CRIT_EXIT();
}
else {
p = 0U; // no more subscribers
}
} while ((p != 0U) &amp;&amp; (lbound &gt; 0U));
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(290, p == 0U);
QF_CRIT_EXIT();
QF_SCHED_UNLOCK_(); // unlock the scheduler
}
// The following garbage collection step decrements the reference counter
// and recycles the event if the counter drops to zero. This covers both
// cases when the event was published with or without any subscribers.
#if (QF_MAX_EPOOL &gt; 0U)
QF::gc(e);
#endif</code>
</operation>
<!--${QF::QActive::subscribe}-->
<operation name="subscribe" type="void" visibility="0x00" properties="0x00">
<specifiers>const noexcept</specifiers>
<!--${QF::QActive::subscribe::sig}-->
<parameter name="sig" type="enum_t const"/>
<code>std::uint_fast8_t const p = static_cast&lt;std::uint_fast8_t&gt;(m_prio);
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(300, (Q_USER_SIG &lt;= sig)
&amp;&amp; (sig &lt; maxPubSignal_)
&amp;&amp; (0U &lt; p) &amp;&amp; (p &lt;= QF_MAX_ACTIVE)
&amp;&amp; (registry_[p] == this));
Q_INVARIANT_INCRIT(302,
subscrList_[sig].m_set.verify_(&amp;subscrList_[sig].m_set_dis));
QS_BEGIN_PRE_(QS_QF_ACTIVE_SUBSCRIBE, m_prio)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(sig); // the signal of this event
QS_OBJ_PRE_(this); // this active object
QS_END_PRE_()
// insert the prio. into the subscriber set
subscrList_[sig].m_set.insert(p);
#ifndef Q_UNSAFE
subscrList_[sig].m_set.update_(&amp;subscrList_[sig].m_set_dis);
#endif
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QF::QActive::unsubscribe}-->
<operation name="unsubscribe" type="void" visibility="0x00" properties="0x00">
<specifiers>const noexcept</specifiers>
<!--${QF::QActive::unsubscribe::sig}-->
<parameter name="sig" type="enum_t const"/>
<code>std::uint_fast8_t const p = static_cast&lt;std::uint_fast8_t&gt;(m_prio);
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(400, (Q_USER_SIG &lt;= sig)
&amp;&amp; (sig &lt; maxPubSignal_)
&amp;&amp; (0U &lt; p) &amp;&amp; (p &lt;= QF_MAX_ACTIVE)
&amp;&amp; (registry_[p] == this));
Q_INVARIANT_INCRIT(402,
subscrList_[sig].m_set.verify_(&amp;subscrList_[sig].m_set_dis));
QS_BEGIN_PRE_(QS_QF_ACTIVE_UNSUBSCRIBE, m_prio)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(sig); // the signal of this event
QS_OBJ_PRE_(this); // this active object
QS_END_PRE_()
// remove the prio. from the subscriber set
subscrList_[sig].m_set.remove(p);
#ifndef Q_UNSAFE
subscrList_[sig].m_set.update_(&amp;subscrList_[sig].m_set_dis);
#endif
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QF::QActive::unsubscribeAll}-->
<operation name="unsubscribeAll" type="void" visibility="0x00" properties="0x00">
<specifiers>const noexcept</specifiers>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
std::uint_fast8_t const p = static_cast&lt;std::uint_fast8_t&gt;(m_prio);
Q_REQUIRE_INCRIT(500, (0U &lt; p) &amp;&amp; (p &lt;= QF_MAX_ACTIVE)
&amp;&amp; (registry_[p] == this));
enum_t const maxPubSig = maxPubSignal_;
QF_MEM_APP();
QF_CRIT_EXIT();
for (enum_t sig = Q_USER_SIG; sig &lt; maxPubSig; ++sig) {
QF_CRIT_ENTRY();
QF_MEM_SYS();
if (subscrList_[sig].m_set.hasElement(p)) {
subscrList_[sig].m_set.remove(p);
#ifndef Q_UNSAFE
subscrList_[sig].m_set.update_(&amp;subscrList_[sig].m_set_dis);
#endif
QS_BEGIN_PRE_(QS_QF_ACTIVE_UNSUBSCRIBE, m_prio)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(sig); // the signal of this event
QS_OBJ_PRE_(this); // this active object
QS_END_PRE_()
}
QF_MEM_APP();
QF_CRIT_EXIT();
QF_CRIT_EXIT_NOP(); // prevent merging critical sections
}</code>
</operation>
<!--${QF::QActive::defer}-->
<operation name="defer" type="bool" visibility="0x00" properties="0x00">
<specifiers>const noexcept</specifiers>
<!--${QF::QActive::defer::eq}-->
<parameter name="eq" type="QEQueue * const"/>
<!--${QF::QActive::defer::e}-->
<parameter name="e" type="QEvt const * const"/>
<code>bool const status = eq-&gt;post(e, 0U, m_prio);
QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QF_ACTIVE_DEFER, m_prio)
QS_TIME_PRE_(); // time stamp
QS_OBJ_PRE_(this); // this active object
QS_OBJ_PRE_(eq); // the deferred queue
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_2U8_PRE_(e-&gt;getPoolNum_(), e-&gt;refCtr_); // poolNum &amp; refCtr
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();
return status;</code>
</operation>
<!--${QF::QActive::recall}-->
<operation name="recall" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QActive::recall::eq}-->
<parameter name="eq" type="QEQueue * const"/>
<code>QEvt const * const e = eq-&gt;get(m_prio); // get evt from deferred queue
QF_CRIT_STAT
bool recalled;
if (e != nullptr) { // event available?
postLIFO(e); // post it to the _front_ of the AO's queue
QF_CRIT_ENTRY();
QF_MEM_SYS();
if (e-&gt;getPoolNum_() != 0U) { // is it a mutable event?
// after posting to the AO's queue the event must be referenced
// at least twice: once in the deferred event queue (eq-&gt;get()
// did NOT decrement the reference counter) and once in the
// AO's event queue.
Q_ASSERT_INCRIT(210, e-&gt;refCtr_ &gt;= 2U);
// we need to decrement the reference counter once, to account
// for removing the event from the deferred event queue.
QEvt_refCtr_dec_(e); // decrement the reference counter
}
QS_BEGIN_PRE_(QS_QF_ACTIVE_RECALL, m_prio)
QS_TIME_PRE_(); // time stamp
QS_OBJ_PRE_(this); // this active object
QS_OBJ_PRE_(eq); // the deferred queue
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_2U8_PRE_(e-&gt;getPoolNum_(), e-&gt;refCtr_); // poolNum &amp; refCtr
QS_END_PRE_()
QF_MEM_APP();
QF_CRIT_EXIT();
recalled = true;
}
else {
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QF_ACTIVE_RECALL_ATTEMPT, m_prio)
QS_TIME_PRE_(); // time stamp
QS_OBJ_PRE_(this); // this active object
QS_OBJ_PRE_(eq); // the deferred queue
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();
recalled = false;
}
return recalled;</code>
</operation>
<!--${QF::QActive::flushDeferred}-->
<operation name="flushDeferred" type="std::uint_fast16_t" visibility="0x00" properties="0x00">
<specifiers>const noexcept</specifiers>
<!--${QF::QActive::flushDeferred::eq}-->
<parameter name="eq" type="QEQueue * const"/>
<!--${QF::QActive::flushDeferred::num = 0xFFFFU}-->
<parameter name="num = 0xFFFFU" type="std::uint_fast16_t const"/>
<code>std::uint_fast16_t n = 0U;
while (n &lt; num) {
QEvt const * const e = eq-&gt;get(m_prio);
if (e != nullptr) {
++n; // count one more flushed event
#if (QF_MAX_EPOOL &gt; 0U)
QF::gc(e); // garbage collect
#endif
}
else {
break;
}
}
return n;</code>
</operation>
<!--${QF::QActive::getPrio}-->
<operation name="getPrio" type="std::uint_fast8_t" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return static_cast&lt;std::uint_fast8_t&gt;(m_prio);</code>
</operation>
<!--${QF::QActive::setPrio}-->
<operation name="setPrio" type="void" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QF::QActive::setPrio::prio}-->
<parameter name="prio" type="QPrioSpec const"/>
<code>m_prio = static_cast&lt;std::uint8_t&gt;(prio &amp; 0xFFU);
m_pthre = static_cast&lt;std::uint8_t&gt;(prio &gt;&gt; 8U);</code>
</operation>
<!--${QF::QActive::getPThre}-->
<operation name="getPThre" type="std::uint_fast8_t" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return static_cast&lt;std::uint_fast8_t&gt;(m_pthre);</code>
</operation>
<!--${QF::QActive::getEQueue}-->
<operation name="getEQueue?def QACTIVE_EQUEUE_TYPE" type="QACTIVE_EQUEUE_TYPE const &amp;" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_eQueue;</code>
</operation>
<!--${QF::QActive::getOsObject}-->
<operation name="getOsObject?def QACTIVE_OS_OBJ_TYPE" type="QACTIVE_OS_OBJ_TYPE const &amp;" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_osObject;</code>
</operation>
<!--${QF::QActive::getThread}-->
<operation name="getThread?def QACTIVE_THREAD_TYPE" type="QACTIVE_THREAD_TYPE const &amp;" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_thread;</code>
</operation>
<!--${QF::QActive::setThread}-->
<operation name="setThread?def QACTIVE_THREAD_TYPE" type="void" visibility="0x00" properties="0x02">
<!--${QF::QActive::setThread::thr}-->
<parameter name="thr" type="QACTIVE_THREAD_TYPE const &amp;"/>
<code>m_thread = thr;</code>
</operation>
<!--${QF::QActive::evtLoop_}-->
<operation name="evtLoop_" type="void" visibility="0x00" properties="0x01">
<!--${QF::QActive::evtLoop_::act}-->
<parameter name="act" type="QActive *"/>
</operation>
<!--${QF::QActive::postFromISR}-->
<operation name="postFromISR?def QF_ISR_API" type="bool" visibility="0x00" properties="0x04">
<specifiers>noexcept</specifiers>
<!--${QF::QActive::postFromISR::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QF::QActive::postFromISR::margin}-->
<parameter name="margin" type="std::uint_fast16_t const"/>
<!--${QF::QActive::postFromISR::par}-->
<parameter name="par" type="void *"/>
<!--${QF::QActive::postFromISR::sender}-->
<parameter name="sender" type="void const * const"/>
</operation>
<!--${QF::QActive::publishFromISR}-->
<operation name="publishFromISR?def QF_ISR_API" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QActive::publishFromISR::e}-->
<parameter name="e" type="QEvt const *"/>
<!--${QF::QActive::publishFromISR::par}-->
<parameter name="par" type="void *"/>
<!--${QF::QActive::publishFromISR::sender}-->
<parameter name="sender" type="void const *"/>
</operation>
</class>
<!--${QF::QMActive}-->
<class name="QMActive" superclass="QF::QActive">
<!--${QF::QMActive::QMActive}-->
<operation name="QMActive" type="" visibility="0x01" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QMActive::QMActive::initial}-->
<parameter name="initial" type="QStateHandler const"/>
<code> : QActive(initial)
m_state.obj = reinterpret_cast&lt;QMsm *&gt;(this)-&gt;topQMState();
m_temp.fun = initial;</code>
</operation>
<!--${QF::QMActive::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x02">
<specifiers>override</specifiers>
<!--${QF::QMActive::init::e}-->
<parameter name="e" type="void const * const"/>
<!--${QF::QMActive::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>reinterpret_cast&lt;QMsm *&gt;(this)-&gt;QMsm::init(e, qsId);</code>
</operation>
<!--${QF::QMActive::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x06">
<specifiers>override</specifiers>
<!--${QF::QMActive::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>this-&gt;init(nullptr, qsId);</code>
</operation>
<!--${QF::QMActive::dispatch}-->
<operation name="dispatch" type="void" visibility="0x00" properties="0x02">
<specifiers>override</specifiers>
<!--${QF::QMActive::dispatch::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QF::QMActive::dispatch::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>reinterpret_cast&lt;QMsm *&gt;(this)-&gt;QMsm::dispatch(e, qsId);</code>
</operation>
<!--${QF::QMActive::isIn}-->
<operation name="isIn" type="bool" visibility="0x00" properties="0x02">
<specifiers>noexcept override</specifiers>
<!--${QF::QMActive::isIn::state}-->
<parameter name="state" type="QStateHandler const"/>
<code>return reinterpret_cast&lt;QMsm *&gt;(this)-&gt;QMsm::isIn(state);</code>
</operation>
<!--${QF::QMActive::getStateHandler}-->
<operation name="getStateHandler?def Q_SPY" type="QStateHandler" visibility="0x00" properties="0x02">
<specifiers>noexcept override</specifiers>
<code>return reinterpret_cast&lt;QMsm *&gt;(this)-&gt;QMsm::getStateHandler();</code>
</operation>
<!--${QF::QMActive::isInState}-->
<operation name="isInState" type="bool" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<!--${QF::QMActive::isInState::st}-->
<parameter name="st" type="QMState const * const"/>
<code>return reinterpret_cast&lt;QMsm const *&gt;(this)-&gt;QMsm::isInState(st);</code>
</operation>
<!--${QF::QMActive::childStateObj}-->
<operation name="childStateObj" type="QMState const *" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<!--${QF::QMActive::childStateObj::parent}-->
<parameter name="parent" type="QMState const * const"/>
<code>return reinterpret_cast&lt;QMsm const *&gt;(this)
-&gt;QMsm::childStateObj(parent);</code>
</operation>
</class>
<!--${QF::QTimeEvt}-->
<class name="QTimeEvt" superclass="QEP::QEvt">
<!--${QF::QTimeEvt::m_next}-->
<attribute name="m_next" type="QTimeEvt * volatile" visibility="0x02" properties="0x00"/>
<!--${QF::QTimeEvt::m_act}-->
<attribute name="m_act" type="void *" visibility="0x02" properties="0x00"/>
<!--${QF::QTimeEvt::m_ctr}-->
<attribute name="m_ctr" type="QTimeEvtCtr volatile" visibility="0x02" properties="0x00"/>
<!--${QF::QTimeEvt::m_interval}-->
<attribute name="m_interval" type="QTimeEvtCtr" visibility="0x02" properties="0x00"/>
<!--${QF::QTimeEvt::timeEvtHead_[QF_MAX_TICK_RATE]}-->
<attribute name="timeEvtHead_[QF_MAX_TICK_RATE]" type="QTimeEvt" visibility="0x00" properties="0x01"/>
<!--${QF::QTimeEvt::QXThread}-->
<attribute name="QXThread" type="friend class" visibility="0x02" properties="0x00"/>
<!--${QF::QTimeEvt::QTimeEvt}-->
<operation name="QTimeEvt" type="" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QTimeEvt::QTimeEvt::act}-->
<parameter name="act" type="QActive * const"/>
<!--${QF::QTimeEvt::QTimeEvt::sig}-->
<parameter name="sig" type="QSignal const"/>
<!--${QF::QTimeEvt::QTimeEvt::tickRate = 0U}-->
<parameter name="tickRate = 0U" type="std::uint_fast8_t const"/>
<code> :
QEvt(sig),
m_next(nullptr),
m_act(act),
m_ctr(0U),
m_interval(0U)
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(300, (sig != 0U)
&amp;&amp; (tickRate &lt; QF_MAX_TICK_RATE));
QF_CRIT_EXIT();
// The refCtr_ attribute is not used in time events, so it is
// reused to hold the tickRate as well as other information
refCtr_ = static_cast&lt;std::uint8_t&gt;(tickRate);</code>
</operation>
<!--${QF::QTimeEvt::armX}-->
<operation name="armX" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QTimeEvt::armX::nTicks}-->
<parameter name="nTicks" type="QTimeEvtCtr const"/>
<!--${QF::QTimeEvt::armX::interval = 0U}-->
<parameter name="interval = 0U" type="QTimeEvtCtr const"/>
<code>std::uint8_t const tickRate = refCtr_ &amp; TE_TICK_RATE;
QTimeEvtCtr const ctr = m_ctr;
#ifdef Q_SPY
std::uint_fast8_t const qsId =
static_cast&lt;QActive const *&gt;(m_act)-&gt;m_prio;
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(400, (m_act != nullptr)
&amp;&amp; (ctr == 0U)
&amp;&amp; (nTicks != 0U)
&amp;&amp; (tickRate &lt; static_cast&lt;std::uint8_t&gt;(QF_MAX_TICK_RATE))
&amp;&amp; (sig &gt;= static_cast&lt;QSignal&gt;(Q_USER_SIG)));
#ifdef Q_UNSAFE
Q_UNUSED_PAR(ctr);
#endif
m_ctr = nTicks;
m_interval = interval;
// is the time event unlinked?
// NOTE: For the duration of a single clock tick of the specified tick
// rate a time event can be disarmed and yet still linked into the list
// because un-linking is performed exclusively in the QF_tickX() function.
if (static_cast&lt;std::uint_fast8_t&gt;(
static_cast&lt;std::uint_fast8_t&gt;(refCtr_) &amp; TE_IS_LINKED) == 0U)
{
// mark as linked
refCtr_ = static_cast&lt;std::uint8_t&gt;(refCtr_ | TE_IS_LINKED);
// The time event is initially inserted into the separate
// &quot;freshly armed&quot; list based on timeEvtHead_[tickRate].act.
// Only later, inside QTimeEvt::tick(), the &quot;freshly armed&quot;
// list is appended to the main list of armed time events based on
// timeEvtHead_[tickRate].next. Again, this is to keep any
// changes to the main list exclusively inside QTimeEvt::tick().
m_next = timeEvtHead_[tickRate].toTimeEvt();
timeEvtHead_[tickRate].m_act = this;
}
QS_BEGIN_PRE_(QS_QF_TIMEEVT_ARM, qsId)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this time event object
QS_OBJ_PRE_(m_act); // the active object
QS_TEC_PRE_(nTicks); // the # ticks
QS_TEC_PRE_(interval); // the interval
QS_U8_PRE_(tickRate); // tick rate
QS_END_PRE_()
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QF::QTimeEvt::disarm}-->
<operation name="disarm" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>#ifdef Q_SPY
std::uint_fast8_t const qsId = static_cast&lt;QActive *&gt;(m_act)-&gt;m_prio;
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
// is the time event actually armed?
bool wasArmed;
if (m_ctr != 0U) {
wasArmed = true;
refCtr_ = static_cast&lt;std::uint8_t&gt;(refCtr_ | TE_WAS_DISARMED);
QS_BEGIN_PRE_(QS_QF_TIMEEVT_DISARM, qsId)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this time event object
QS_OBJ_PRE_(m_act); // the target AO
QS_TEC_PRE_(m_ctr); // the # ticks
QS_TEC_PRE_(m_interval); // the interval
QS_U8_PRE_(refCtr_&amp; TE_TICK_RATE); // tick rate
QS_END_PRE_()
m_ctr = 0U; // schedule removal from the list
}
else { // the time event was already disarmed automatically
wasArmed = false;
refCtr_ = static_cast&lt;std::uint8_t&gt;(refCtr_
&amp; static_cast&lt;std::uint8_t&gt;(~TE_WAS_DISARMED));
QS_BEGIN_PRE_(QS_QF_TIMEEVT_DISARM_ATTEMPT, qsId)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this time event object
QS_OBJ_PRE_(m_act); // the target AO
QS_U8_PRE_(refCtr_&amp; TE_TICK_RATE); // tick rate
QS_END_PRE_()
}
QF_MEM_APP();
QF_CRIT_EXIT();
return wasArmed;</code>
</operation>
<!--${QF::QTimeEvt::rearm}-->
<operation name="rearm" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QTimeEvt::rearm::nTicks}-->
<parameter name="nTicks" type="QTimeEvtCtr const"/>
<code>std::uint8_t const tickRate = refCtr_ &amp; TE_TICK_RATE;
#ifdef Q_SPY
std::uint_fast8_t const qsId = static_cast&lt;QActive *&gt;(m_act)-&gt;m_prio;
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(600, (m_act != nullptr)
&amp;&amp; (tickRate &lt; static_cast&lt;std::uint8_t&gt;(QF_MAX_TICK_RATE))
&amp;&amp; (nTicks != 0U)
&amp;&amp; (sig &gt;= static_cast&lt;QSignal&gt;(Q_USER_SIG)));
// is the time evt not running?
bool wasArmed;
if (m_ctr == 0U) {
wasArmed = false;
// NOTE: For a duration of a single clock tick of the specified
// tick rate a time event can be disarmed and yet still linked into
// the list, because unlinking is performed exclusively in the
// QTimeEvt::tickX() function.
// is the time event unlinked?
if (static_cast&lt;std::uint8_t&gt;(refCtr_ &amp; TE_IS_LINKED) == 0U) {
// mark as linked
refCtr_ = static_cast&lt;std::uint8_t&gt;(refCtr_ | TE_IS_LINKED);
// The time event is initially inserted into the separate
// &quot;freshly armed&quot; list based on timeEvtHead_[tickRate].act.
// Only later, inside QTimeEvt::tick(), the &quot;freshly armed&quot;
// list is appended to the main list of armed time events based on
// timeEvtHead_[tickRate].next. Again, this is to keep any
// changes to the main list exclusively inside QTimeEvt::tick().
m_next = timeEvtHead_[tickRate].toTimeEvt();
timeEvtHead_[tickRate].m_act = this;
}
}
else { // the time event was armed
wasArmed = true;
}
m_ctr = nTicks; // re-load the tick counter (shift the phasing)
QS_BEGIN_PRE_(QS_QF_TIMEEVT_REARM, qsId)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this time event object
QS_OBJ_PRE_(m_act); // the target AO
QS_TEC_PRE_(m_ctr); // the # ticks
QS_TEC_PRE_(m_interval); // the interval
QS_2U8_PRE_(tickRate, (wasArmed ? 1U : 0U));
QS_END_PRE_()
QF_MEM_APP();
QF_CRIT_EXIT();
return wasArmed;</code>
</operation>
<!--${QF::QTimeEvt::wasDisarmed}-->
<operation name="wasDisarmed" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
std::uint8_t const isDisarmed = refCtr_ &amp; TE_WAS_DISARMED;
refCtr_ = static_cast&lt;std::uint8_t&gt;(refCtr_ | TE_WAS_DISARMED);
QF_MEM_APP();
QF_CRIT_EXIT();
return isDisarmed != 0U;</code>
</operation>
<!--${QF::QTimeEvt::getAct}-->
<operation name="getAct" type="void const *" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_act;</code>
</operation>
<!--${QF::QTimeEvt::getCtr}-->
<operation name="getCtr" type="QTimeEvtCtr" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_ctr;</code>
</operation>
<!--${QF::QTimeEvt::getInterval}-->
<operation name="getInterval" type="QTimeEvtCtr" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_interval;</code>
</operation>
<!--${QF::QTimeEvt::tick}-->
<operation name="tick" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QTimeEvt::tick::tickRate}-->
<parameter name="tickRate" type="std::uint_fast8_t const"/>
<!--${QF::QTimeEvt::tick::sender}-->
<parameter name="sender" type="void const * const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(sender);
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(100, tickRate &lt; Q_DIM(timeEvtHead_));
QTimeEvt *prev = &amp;timeEvtHead_[tickRate];
QS_BEGIN_PRE_(QS_QF_TICK, 0U)
prev-&gt;m_ctr = (prev-&gt;m_ctr + 1U);
QS_TEC_PRE_(prev-&gt;m_ctr); // tick ctr
QS_U8_PRE_(tickRate); // tick rate
QS_END_PRE_()
// scan the linked-list of time events at this rate...
std::uint_fast8_t lbound = 2U*QF_MAX_ACTIVE; // fixed upper loop bound
for (; lbound &gt; 0U; --lbound) {
QTimeEvt *e = prev-&gt;m_next; // advance down the time evt. list
if (e == nullptr) { // end of the list?
// any new time events armed since the last run of tick()?
if (timeEvtHead_[tickRate].m_act != nullptr) {
// sanity check
Q_ASSERT_INCRIT(110, prev != nullptr);
prev-&gt;m_next = timeEvtHead_[tickRate].toTimeEvt();
timeEvtHead_[tickRate].m_act = nullptr;
e = prev-&gt;m_next; // switch to the new list
}
else { // all currently armed time events are processed
break; // terminate the for-loop
}
}
// the time event 'e' must be valid
Q_INVARIANT_INCRIT(112, QEvt::verify_(e));
if (e-&gt;m_ctr == 0U) { // time event scheduled for removal?
prev-&gt;m_next = e-&gt;m_next;
// mark time event 'e' as NOT linked
e-&gt;refCtr_ = static_cast&lt;std::uint8_t&gt;(e-&gt;refCtr_
&amp; static_cast&lt;std::uint8_t&gt;(~TE_IS_LINKED));
// do NOT advance the prev pointer
QF_MEM_APP();
QF_CRIT_EXIT(); // exit crit. section to reduce latency
// NOTE: prevent merging critical sections
// In some QF ports the critical section exit takes effect only
// on the next machine instruction. If the next instruction is
// another entry to a critical section, the critical section
// might not be really exited, but rather the two adjacent
// critical sections would be MERGED. The QF_CRIT_EXIT_NOP()
// macro contains minimal code required to prevent such merging
// of critical sections in QF ports, in which it can occur.
QF_CRIT_EXIT_NOP();
}
else {
e-&gt;m_ctr = (e-&gt;m_ctr - 1U);
if (e-&gt;m_ctr == 0U) { // is time evt about to expire?
QActive * const act = e-&gt;toActive();
if (e-&gt;m_interval != 0U) { // periodic time evt?
e-&gt;m_ctr = e-&gt;m_interval; // rearm the time event
prev = e; // advance to this time event
}
else { // one-shot time event: automatically disarm
prev-&gt;m_next = e-&gt;m_next;
// mark time event 'e' as NOT linked
e-&gt;refCtr_ = static_cast&lt;std::uint8_t&gt;(e-&gt;refCtr_
&amp; static_cast&lt;std::uint8_t&gt;(~TE_IS_LINKED));
// do NOT advance the prev pointer
QS_BEGIN_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act-&gt;m_prio)
QS_OBJ_PRE_(e); // this time event object
QS_OBJ_PRE_(act); // the target AO
QS_U8_PRE_(tickRate); // tick rate
QS_END_PRE_()
}
QS_BEGIN_PRE_(QS_QF_TIMEEVT_POST, act-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(e); // the time event object
QS_SIG_PRE_(e-&gt;sig); // signal of this time event
QS_OBJ_PRE_(act); // the target AO
QS_U8_PRE_(tickRate); // tick rate
QS_END_PRE_()
#ifdef QXK_HPP_
if (e-&gt;sig &lt; Q_USER_SIG) {
QXThread::timeout_(act);
QF_MEM_APP();
QF_CRIT_EXIT();
}
else {
QF_MEM_APP();
QF_CRIT_EXIT(); // exit crit. section before posting
// act-&gt;POST() asserts if the queue overflows
act-&gt;POST(e, sender);
}
#else
QF_MEM_APP();
QF_CRIT_EXIT(); // exit crit. section before posting
// act-&gt;POST() asserts if the queue overflows
act-&gt;POST(e, sender);
#endif
}
else {
prev = e; // advance to this time event
QF_MEM_APP();
QF_CRIT_EXIT(); // exit crit. section to reduce latency
// prevent merging critical sections, see NOTE above
QF_CRIT_EXIT_NOP();
}
}
QF_CRIT_ENTRY(); // re-enter crit. section to continue the loop
QF_MEM_SYS();
}
Q_ENSURE_INCRIT(190, lbound &gt; 0U);
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QF::QTimeEvt::tick1_}-->
<operation name="tick1_?def Q_UTEST" type="void" visibility="0x00" properties="0x01">
<!--${QF::QTimeEvt::tick1_::tickRate}-->
<parameter name="tickRate" type="std::uint_fast8_t const"/>
<!--${QF::QTimeEvt::tick1_::sender}-->
<parameter name="sender" type="void const * const"/>
</operation>
<!--${QF::QTimeEvt::tickFromISR}-->
<operation name="tickFromISR?def QF_ISR_API" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QTimeEvt::tickFromISR::tickRate}-->
<parameter name="tickRate" type="std::uint_fast8_t const"/>
<!--${QF::QTimeEvt::tickFromISR::par}-->
<parameter name="par" type="void *"/>
<!--${QF::QTimeEvt::tickFromISR::sender}-->
<parameter name="sender" type="void const *"/>
</operation>
<!--${QF::QTimeEvt::noActive}-->
<operation name="noActive" type="bool" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QTimeEvt::noActive::tickRate}-->
<parameter name="tickRate" type="std::uint_fast8_t const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(800, tickRate &lt; QF_MAX_TICK_RATE);
QF_CRIT_EXIT();
bool inactive;
if (timeEvtHead_[tickRate].m_next != nullptr) {
inactive = false;
}
else if (timeEvtHead_[tickRate].m_act != nullptr) {
inactive = false;
}
else {
inactive = true;
}
return inactive;</code>
</operation>
<!--${QF::QTimeEvt::toActive}-->
<operation name="toActive" type="QActive *" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<code>return static_cast&lt;QActive *&gt;(m_act);</code>
</operation>
<!--${QF::QTimeEvt::toTimeEvt}-->
<operation name="toTimeEvt" type="QTimeEvt *" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<code>return static_cast&lt;QTimeEvt *&gt;(m_act);</code>
</operation>
<!--${QF::QTimeEvt::QTimeEvt}-->
<operation name="QTimeEvt" type="" visibility="0x02" properties="0x00">
<specifiers>noexcept</specifiers>
<code> :
QEvt(0U),
m_next(nullptr),
m_act(nullptr),
m_ctr(0U),
m_interval(0U)
// The refCtr_ attribute is not used in time events, so it is
// reused to hold the tickRate as well as other information
refCtr_ = 0U; // default rate 0</code>
</operation>
<!--${QF::QTimeEvt::QTimeEvt}-->
<operation name="QTimeEvt" type="" visibility="0x02" properties="0x00">
<specifiers>= delete</specifiers>
<!--${QF::QTimeEvt::QTimeEvt::other}-->
<parameter name="other" type="QTimeEvt const &amp;"/>
</operation>
<!--${QF::QTimeEvt::operator=}-->
<operation name="operator=" type="QTimeEvt &amp;" visibility="0x02" properties="0x00">
<specifiers>= delete</specifiers>
<!--${QF::QTimeEvt::operator=::other}-->
<parameter name="other" type="QTimeEvt const &amp;"/>
</operation>
</class>
<!--${QF::QTicker}-->
<class name="QTicker" superclass="QF::QActive">
<!--${QF::QTicker::QTicker}-->
<operation name="QTicker" type="explicit" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QTicker::QTicker::tickRate}-->
<parameter name="tickRate" type="std::uint_fast8_t const"/>
<code>: QActive(nullptr)
// reuse m_head for tick-rate
m_eQueue.m_head = static_cast&lt;QEQueueCtr&gt;(tickRate);</code>
</operation>
<!--${QF::QTicker::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x00">
<specifiers>override</specifiers>
<!--${QF::QTicker::init::e}-->
<parameter name="e" type="void const * const"/>
<!--${QF::QTicker::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>Q_UNUSED_PAR(e);
Q_UNUSED_PAR(qsId);
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
m_eQueue.m_tail = 0U;
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QF::QTicker::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x06">
<specifiers>override</specifiers>
<!--${QF::QTicker::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>this-&gt;init(nullptr, qsId);</code>
</operation>
<!--${QF::QTicker::dispatch}-->
<operation name="dispatch" type="void" visibility="0x00" properties="0x00">
<specifiers>override</specifiers>
<!--${QF::QTicker::dispatch::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QF::QTicker::dispatch::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>Q_UNUSED_PAR(e);
Q_UNUSED_PAR(qsId);
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
QEQueueCtr nTicks = m_eQueue.m_tail; // save # of ticks
m_eQueue.m_tail = 0U; // clear the # ticks
QF_MEM_APP();
QF_CRIT_EXIT();
for (; nTicks &gt; 0U; --nTicks) {
QTimeEvt::tick(static_cast&lt;std::uint_fast8_t&gt;(m_eQueue.m_head),
this);
}</code>
</operation>
<!--${QF::QTicker::trig_}-->
<operation name="trig_" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QTicker::trig_::sender}-->
<parameter name="sender" type="void const * const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(sender);
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
if (m_eQueue.m_frontEvt == nullptr) {
static QEvt const tickEvt(0U); // immutable event
m_eQueue.m_frontEvt = &amp;tickEvt; // deliver event directly
m_eQueue.m_nFree = (m_eQueue.m_nFree - 1U); // one less free event
QACTIVE_EQUEUE_SIGNAL_(this); // signal the event queue
}
// account for one more tick event
m_eQueue.m_tail = (m_eQueue.m_tail + 1U);
QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(sender); // the sender object
QS_SIG_PRE_(0U); // the signal of the event
QS_OBJ_PRE_(this); // this active object
QS_2U8_PRE_(0U, 0U); // poolNum &amp; refCtr
QS_EQC_PRE_(0U); // # free entries
QS_EQC_PRE_(0U); // min # free entries
QS_END_PRE_()
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
</class>
<!--${QF::QEQueue}-->
<class name="QEQueue">
<!--${QF::QEQueue::m_frontEvt}-->
<attribute name="m_frontEvt" type="QEvt const * volatile" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::m_ring}-->
<attribute name="m_ring" type="QEvt const **" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::m_end}-->
<attribute name="m_end" type="QEQueueCtr" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::m_head}-->
<attribute name="m_head" type="QEQueueCtr volatile" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::m_tail}-->
<attribute name="m_tail" type="QEQueueCtr volatile" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::m_nFree}-->
<attribute name="m_nFree" type="QEQueueCtr volatile" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::m_nMin}-->
<attribute name="m_nMin" type="QEQueueCtr" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::QActive}-->
<attribute name="QActive" type="friend class" visibility="0x02" properties="0x00">
<documentation>// friends...</documentation>
</attribute>
<!--${QF::QEQueue::QTicker}-->
<attribute name="QTicker" type="friend class" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::QXMutex}-->
<attribute name="QXMutex" type="friend class" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::QXThread}-->
<attribute name="QXThread" type="friend class" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::QEQueue}-->
<operation name="QEQueue" type="" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<code> : m_frontEvt(nullptr),
m_ring(nullptr),
m_end(0U),
m_head(0U),
m_tail(0U),
m_nFree(0U),
m_nMin(0U)</code>
</operation>
<!--${QF::QEQueue::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QEQueue::init::qSto[]}-->
<parameter name="qSto[]" type="QEvt const *"/>
<!--${QF::QEQueue::init::qLen}-->
<parameter name="qLen" type="std::uint_fast16_t const"/>
<code>m_frontEvt = nullptr; // no events in the queue
m_ring = &amp;qSto[0];
m_end = static_cast&lt;QEQueueCtr&gt;(qLen);
if (qLen &gt; 0U) {
m_head = 0U;
m_tail = 0U;
}
m_nFree = static_cast&lt;QEQueueCtr&gt;(qLen + 1U); //+1 for frontEvt
m_nMin = m_nFree;</code>
</operation>
<!--${QF::QEQueue::post}-->
<operation name="post" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QEQueue::post::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QF::QEQueue::post::margin}-->
<parameter name="margin" type="std::uint_fast16_t const"/>
<!--${QF::QEQueue::post::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(qsId);
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(200, e != nullptr);
QEQueueCtr nFree = m_nFree; // get volatile into temporary
// required margin available?
bool status;
if (((margin == QF::NO_MARGIN) &amp;&amp; (nFree &gt; 0U))
|| (nFree &gt; static_cast&lt;QEQueueCtr&gt;(margin)))
{
// is it a mutable event?
if (e-&gt;getPoolNum_() != 0U) {
QEvt_refCtr_inc_(e); // increment the reference counter
}
--nFree; // one free entry just used up
m_nFree = nFree; // update the original
if (m_nMin &gt; nFree) {
m_nMin = nFree; // update minimum so far
}
QS_BEGIN_PRE_(QS_QF_EQUEUE_POST, qsId)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(e-&gt;sig); // the signal of this event
QS_OBJ_PRE_(this); // this queue object
QS_2U8_PRE_(e-&gt;getPoolNum_(), e-&gt;refCtr_); // poolNum &amp; refCtr
QS_EQC_PRE_(nFree); // # free entries
QS_EQC_PRE_(m_nMin); // min # free entries
QS_END_PRE_()
if (m_frontEvt == nullptr) { // was the queue empty?
m_frontEvt = e; // deliver event directly
}
else { // queue was not empty, insert event into the ring-buffer
// insert event into the ring buffer (FIFO)
m_ring[m_head] = e; // insert e into buffer
// need to wrap?
if (m_head == 0U) {
m_head = m_end; // wrap around
}
m_head = (m_head - 1U);
}
status = true; // event posted successfully
}
else { // event cannot be posted
// dropping events must be acceptable
Q_ASSERT_INCRIT(210, margin != QF::NO_MARGIN);
QS_BEGIN_PRE_(QS_QF_EQUEUE_POST_ATTEMPT, qsId)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(e-&gt;sig); // the signal of this event
QS_OBJ_PRE_(this); // this queue object
QS_2U8_PRE_(e-&gt;getPoolNum_(), e-&gt;refCtr_); // poolNum &amp; refCtr
QS_EQC_PRE_(nFree); // # free entries
QS_EQC_PRE_(margin); // margin requested
QS_END_PRE_()
status = false; // event not posted
}
QF_MEM_APP();
QF_CRIT_EXIT();
return status;</code>
</operation>
<!--${QF::QEQueue::postLIFO}-->
<operation name="postLIFO" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QEQueue::postLIFO::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QF::QEQueue::postLIFO::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(qsId);
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
QEQueueCtr nFree = m_nFree; // get volatile into temporary
Q_REQUIRE_INCRIT(300, nFree != 0U);
if (e-&gt;getPoolNum_() != 0U) { // is it a mutable event?
QEvt_refCtr_inc_(e); // increment the reference counter
}
--nFree; // one free entry just used up
m_nFree = nFree; // update the original
if (m_nMin &gt; nFree) {
m_nMin = nFree; // update minimum so far
}
QS_BEGIN_PRE_(QS_QF_EQUEUE_POST_LIFO, qsId)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(e-&gt;sig); // the signal of this event
QS_OBJ_PRE_(this); // this queue object
QS_2U8_PRE_(e-&gt;getPoolNum_(), e-&gt;refCtr_); // poolNum &amp; refCtr
QS_EQC_PRE_(nFree); // # free entries
QS_EQC_PRE_(m_nMin); // min # free entries
QS_END_PRE_()
QEvt const * const frontEvt = m_frontEvt; // read into temporary
m_frontEvt = e; // deliver event directly to the front of the queue
if (frontEvt != nullptr) { // was the queue not empty?
m_tail = (m_tail + 1U);
if (m_tail == m_end) { // need to wrap the tail?
m_tail = 0U; // wrap around
}
m_ring[m_tail] = frontEvt; // buffer the old front evt
}
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QF::QEQueue::get}-->
<operation name="get" type="QEvt const *" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QEQueue::get::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(qsId);
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
QEvt const * const e = m_frontEvt; // always remove evt from the front
if (e != nullptr) { // was the queue not empty?
QEQueueCtr const nFree = m_nFree + 1U;
m_nFree = nFree; // update the # free
// any events in the the ring buffer?
if (nFree &lt;= m_end) {
m_frontEvt = m_ring[m_tail]; // remove from the tail
if (m_tail == 0U) { // need to wrap?
m_tail = m_end; // wrap around
}
m_tail = (m_tail - 1U);
QS_BEGIN_PRE_(QS_QF_EQUEUE_GET, qsId)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(e-&gt;sig); // the signal of this event
QS_OBJ_PRE_(this); // this queue object
QS_2U8_PRE_(e-&gt;getPoolNum_(), e-&gt;refCtr_); // poolNum &amp; refCtr
QS_EQC_PRE_(nFree); // # free entries
QS_END_PRE_()
}
else {
m_frontEvt = nullptr; // queue becomes empty
// all entries in the queue must be free (+1 for fronEvt)
Q_ASSERT_INCRIT(410, nFree == (m_end + 1U));
QS_BEGIN_PRE_(QS_QF_EQUEUE_GET_LAST, qsId)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(e-&gt;sig); // the signal of this event
QS_OBJ_PRE_(this); // this queue object
QS_2U8_PRE_(e-&gt;getPoolNum_(), e-&gt;refCtr_); // poolNum &amp; refCtr
QS_END_PRE_()
}
}
QF_MEM_APP();
QF_CRIT_EXIT();
return e;</code>
</operation>
<!--${QF::QEQueue::getNFree}-->
<operation name="getNFree" type="QEQueueCtr" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_nFree;</code>
</operation>
<!--${QF::QEQueue::getNMin}-->
<operation name="getNMin" type="QEQueueCtr" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_nMin;</code>
</operation>
<!--${QF::QEQueue::isEmpty}-->
<operation name="isEmpty" type="bool" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_frontEvt == nullptr;</code>
</operation>
<!--${QF::QEQueue::QEQueue}-->
<operation name="QEQueue" type="" visibility="0x02" properties="0x00">
<specifiers>= delete</specifiers>
<!--${QF::QEQueue::QEQueue::other}-->
<parameter name="other" type="QEQueue const &amp;"/>
</operation>
<!--${QF::QEQueue::operator=}-->
<operation name="operator=" type="QEQueue &amp;" visibility="0x02" properties="0x00">
<specifiers>= delete</specifiers>
<!--${QF::QEQueue::operator=::other}-->
<parameter name="other" type="QEQueue const &amp;"/>
</operation>
</class>
<!--${QF::QFreeBlock}-->
<class name="QFreeBlock">
<!--${QF::QFreeBlock::m_next}-->
<attribute name="m_next" type="QFreeBlock *" visibility="0x02" properties="0x00"/>
<!--${QF::QFreeBlock::m_next_dis}-->
<attribute name="m_next_dis?ndef Q_UNSAFE" type="std::uintptr_t" visibility="0x02" properties="0x00"/>
<!--${QF::QFreeBlock::QMPool}-->
<attribute name="QMPool" type="friend class" visibility="0x02" properties="0x00"/>
</class>
<!--${QF::QMPool}-->
<class name="QMPool">
<!--${QF::QMPool::m_start}-->
<attribute name="m_start" type="QFreeBlock *" visibility="0x02" properties="0x00"/>
<!--${QF::QMPool::m_end}-->
<attribute name="m_end" type="QFreeBlock *" visibility="0x02" properties="0x00"/>
<!--${QF::QMPool::m_free_head}-->
<attribute name="m_free_head" type="QFreeBlock * volatile" visibility="0x02" properties="0x00"/>
<!--${QF::QMPool::m_blockSize}-->
<attribute name="m_blockSize" type="QMPoolSize" visibility="0x02" properties="0x00"/>
<!--${QF::QMPool::m_nTot}-->
<attribute name="m_nTot" type="QMPoolCtr" visibility="0x02" properties="0x00"/>
<!--${QF::QMPool::m_nFree}-->
<attribute name="m_nFree" type="QMPoolCtr volatile" visibility="0x02" properties="0x00"/>
<!--${QF::QMPool::m_nMin}-->
<attribute name="m_nMin" type="QMPoolCtr" visibility="0x02" properties="0x00"/>
<!--${QF::QMPool::QMPool}-->
<operation name="QMPool" type="" visibility="0x00" properties="0x02">
<code> : m_start(nullptr),
m_end(nullptr),
m_free_head(nullptr),
m_blockSize(0U),
m_nTot(0U),
m_nFree(0U),
m_nMin(0U)</code>
</operation>
<!--${QF::QMPool::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QMPool::init::poolSto}-->
<parameter name="poolSto" type="void * const"/>
<!--${QF::QMPool::init::poolSize}-->
<parameter name="poolSize" type="std::uint_fast32_t const"/>
<!--${QF::QMPool::init::blockSize}-->
<parameter name="blockSize" type="std::uint_fast16_t const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(100, (poolSto != nullptr)
&amp;&amp; (poolSize &gt;= static_cast&lt;std::uint_fast32_t&gt;(sizeof(QFreeBlock)))
&amp;&amp; (static_cast&lt;std::uint_fast16_t&gt;(blockSize + sizeof(QFreeBlock))
&gt; blockSize));
m_free_head = static_cast&lt;QFreeBlock *&gt;(poolSto);
// find # free blocks in a memory block, NO DIVISION
m_blockSize = static_cast&lt;QMPoolSize&gt;(sizeof(QFreeBlock));
std::uint_fast16_t nblocks = 1U;
while (m_blockSize &lt; static_cast&lt;QMPoolSize&gt;(blockSize)) {
m_blockSize += static_cast&lt;QMPoolSize&gt;(sizeof(QFreeBlock));
++nblocks;
}
// the pool buffer must fit at least one rounded-up block
Q_ASSERT_INCRIT(110, poolSize &gt;= m_blockSize);
// start at the head of the free list
QFreeBlock *fb = m_free_head;
m_nTot = 1U; // the last block already in the list
// chain all blocks together in a free-list...
for (std::uint_fast32_t size = poolSize - m_blockSize;
size &gt;= static_cast&lt;std::uint_fast32_t&gt;(m_blockSize);
size -= static_cast&lt;std::uint_fast32_t&gt;(m_blockSize))
{
fb-&gt;m_next = &amp;fb[nblocks]; // point next link to next block
#ifndef Q_UNSAFE
fb-&gt;m_next_dis = ~Q_UINTPTR_CAST_(fb-&gt;m_next);
#endif
fb = fb-&gt;m_next; // advance to the next block
++m_nTot; // one more free block in the pool
}
fb-&gt;m_next = nullptr; // the last link points to NULL
#ifndef Q_UNSAFE
fb-&gt;m_next_dis = ~Q_UINTPTR_CAST_(fb-&gt;m_next);
#endif
fb-&gt;m_next = nullptr; // the last link points to NULL
m_nFree = m_nTot; // all blocks are free
m_nMin = m_nTot; // the minimum # free blocks
m_start = static_cast&lt;QFreeBlock *&gt;(poolSto); // original start
m_end = fb; // the last block in this pool
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QF::QMPool::get}-->
<operation name="get" type="void *" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QMPool::get::margin}-->
<parameter name="margin" type="std::uint_fast16_t const"/>
<!--${QF::QMPool::get::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(qsId);
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
// have more free blocks than the requested margin?
QFreeBlock *fb;
if (m_nFree &gt; static_cast&lt;QMPoolCtr&gt;(margin)) {
fb = m_free_head; // get a free block
// a free block must be valid
Q_ASSERT_INCRIT(300, fb != nullptr);
QFreeBlock * const fb_next = fb-&gt;m_next;
// the free block must have integrity (duplicate inverse storage)
Q_INVARIANT_INCRIT(302, Q_UINTPTR_CAST_(fb_next)
== static_cast&lt;std::uintptr_t&gt;(~fb-&gt;m_next_dis));
m_nFree = (m_nFree - 1U); // one free block less
if (m_nFree == 0U) { // is the pool becoming empty?
// pool is becoming empty, so the next free block must be NULL
Q_ASSERT_INCRIT(320, fb_next == nullptr);
m_nMin = 0U; // remember that the pool got empty
}
else {
// invariant:
// The pool is not empty, so the next free-block pointer,
// so the next free block must be in range.
// NOTE: The next free block pointer can fall out of range
// when the client code writes past the memory block, thus
// corrupting the next block.
Q_ASSERT_INCRIT(330,
QF_PTR_RANGE_(fb_next, m_start, m_end));
// is the # free blocks the new minimum so far?
if (m_nMin &gt; m_nFree) {
m_nMin = m_nFree; // remember the minimum so far
}
}
m_free_head = fb_next; // set the head to the next free block
QS_BEGIN_PRE_(QS_QF_MPOOL_GET, qsId)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this memory pool
QS_MPC_PRE_(m_nFree); // # of free blocks in the pool
QS_MPC_PRE_(m_nMin); // min # free blocks ever in the pool
QS_END_PRE_()
}
else { // don't have enough free blocks at this point
fb = nullptr;
QS_BEGIN_PRE_(QS_QF_MPOOL_GET_ATTEMPT, qsId)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this memory pool
QS_MPC_PRE_(m_nFree); // # of free blocks in the pool
QS_MPC_PRE_(margin); // the requested margin
QS_END_PRE_()
}
QF_MEM_APP();
QF_CRIT_EXIT();
return fb; // return the block or nullptr to the caller</code>
</operation>
<!--${QF::QMPool::put}-->
<operation name="put" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QMPool::put::block}-->
<parameter name="block" type="void * const"/>
<!--${QF::QMPool::put::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(qsId);
#endif
QFreeBlock * const fb = static_cast&lt;QFreeBlock *&gt;(block);
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(200, (m_nFree &lt; m_nTot)
&amp;&amp; QF_PTR_RANGE_(fb, m_start, m_end));
fb-&gt;m_next = m_free_head; // link into list
#ifndef Q_UNSAFE
fb-&gt;m_next_dis = static_cast&lt;std::uintptr_t&gt;(
~Q_UINTPTR_CAST_(fb-&gt;m_next));
#endif
// set as new head of the free list
m_free_head = fb;
m_nFree = m_nFree + 1U; // one more free block in this pool
QS_BEGIN_PRE_(QS_QF_MPOOL_PUT, qsId)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this memory pool
QS_MPC_PRE_(m_nFree); // the # free blocks in the pool
QS_END_PRE_()
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QF::QMPool::getBlockSize}-->
<operation name="getBlockSize" type="QMPoolSize" visibility="0x00" properties="0x00">
<specifiers>const noexcept</specifiers>
<code>return m_blockSize;</code>
</operation>
<!--${QF::QMPool::getNMin}-->
<operation name="getNMin" type="QMPoolCtr" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_nMin;</code>
</operation>
<!--${QF::QMPool::getNFree}-->
<operation name="getNFree" type="QMPoolCtr" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_nFree;</code>
</operation>
<!--${QF::QMPool::QMPool}-->
<operation name="QMPool" type="" visibility="0x02" properties="0x00">
<specifiers>= delete</specifiers>
<!--${QF::QMPool::QMPool::other}-->
<parameter name="other" type="QEQueue const &amp;"/>
</operation>
<!--${QF::QMPool::operator=}-->
<operation name="operator=" type="QMPool &amp;" visibility="0x02" properties="0x00">
<specifiers>= delete</specifiers>
<!--${QF::QMPool::operator=::other}-->
<parameter name="other" type="QMPool const &amp;"/>
</operation>
<!--${QF::QMPool::getFromISR}-->
<operation name="getFromISR?def QF_ISR_API" type="void *" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QMPool::getFromISR::margin}-->
<parameter name="margin" type="std::uint_fast16_t const"/>
<!--${QF::QMPool::getFromISR::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
</operation>
<!--${QF::QMPool::putFromISR}-->
<operation name="putFromISR?def QF_ISR_API" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QMPool::putFromISR::b}-->
<parameter name="b" type="void * const"/>
<!--${QF::QMPool::putFromISR::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
</operation>
</class>
<!--${QF::QF-pkg}-->
<package name="QF-pkg" stereotype="0x02" namespace="QF::">
<!--${QF::QF-pkg::Attr}-->
<class name="Attr">
<!--${QF::QF-pkg::Attr::ePool_[QF_MAX_EPOOL]}-->
<attribute name="ePool_[QF_MAX_EPOOL]? (QF_MAX_EPOOL &gt; 0U)" type="QF_EPOOL_TYPE_" visibility="0x00" properties="0x00"/>
<!--${QF::QF-pkg::Attr::maxPool_}-->
<attribute name="maxPool_? (QF_MAX_EPOOL &gt; 0U)" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QF::QF-pkg::Attr::dummy}-->
<attribute name="dummy? (QF_MAX_EPOOL == 0U)" type="std::uint8_t" visibility="0x00" properties="0x00"/>
</class>
<!--${QF::QF-pkg::priv_}-->
<attribute name="priv_" type="QF::Attr" visibility="0x00" properties="0x00"/>
<!--${QF::QF-pkg::bzero_}-->
<operation name="bzero_" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QF-pkg::bzero_::start}-->
<parameter name="start" type="void * const"/>
<!--${QF::QF-pkg::bzero_::len}-->
<parameter name="len" type="std::uint_fast16_t const"/>
<code>std::uint8_t *ptr = static_cast&lt;std::uint8_t *&gt;(start);
for (std::uint_fast16_t n = len; n &gt; 0U; --n) {
*ptr = 0U;
++ptr;
}</code>
</operation>
</package>
<!--${QF::QF-base}-->
<package name="QF-base" stereotype="0x02" namespace="QF::">
<!--${QF::QF-base::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x01"/>
<!--${QF::QF-base::stop}-->
<operation name="stop" type="void" visibility="0x00" properties="0x01"/>
<!--${QF::QF-base::run}-->
<operation name="run" type="int_t" visibility="0x00" properties="0x01"/>
<!--${QF::QF-base::onStartup}-->
<operation name="onStartup" type="void" visibility="0x00" properties="0x01"/>
<!--${QF::QF-base::onCleanup}-->
<operation name="onCleanup" type="void" visibility="0x00" properties="0x01"/>
<!--${QF::QF-base::psInit}-->
<operation name="psInit" type="void" visibility="0x00" properties="0x03">
<specifiers>noexcept</specifiers>
<documentation>//! @deprecated</documentation>
<!--${QF::QF-base::psInit::subscrSto}-->
<parameter name="subscrSto" type="QSubscrList * const"/>
<!--${QF::QF-base::psInit::maxSignal}-->
<parameter name="maxSignal" type="enum_t const"/>
<code>QActive::psInit(subscrSto, maxSignal);</code>
</operation>
<!--${QF::QF-base::publish_}-->
<operation name="publish_" type="void" visibility="0x00" properties="0x03">
<specifiers>noexcept</specifiers>
<documentation>//! @deprecated</documentation>
<!--${QF::QF-base::publish_::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QF::QF-base::publish_::sender}-->
<parameter name="sender" type="void const * const"/>
<!--${QF::QF-base::publish_::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>QActive::publish_(e, sender, qsId);</code>
</operation>
<!--${QF::QF-base::tick}-->
<operation name="tick" type="void" visibility="0x00" properties="0x03">
<specifiers>noexcept</specifiers>
<documentation>//! @deprecated</documentation>
<!--${QF::QF-base::tick::tickRate}-->
<parameter name="tickRate" type="std::uint_fast8_t const"/>
<!--${QF::QF-base::tick::sender}-->
<parameter name="sender" type="void const * const"/>
<code>QTimeEvt::tick(tickRate, sender);</code>
</operation>
<!--${QF::QF-base::getQueueMin}-->
<operation name="getQueueMin" type="std::uint_fast16_t" visibility="0x00" properties="0x03">
<specifiers>noexcept</specifiers>
<documentation>//! @deprecated</documentation>
<!--${QF::QF-base::getQueueMin::prio}-->
<parameter name="prio" type="std::uint_fast8_t const"/>
<code>return QActive::getQueueMin(prio);</code>
</operation>
<!--${QF::QF-base::NO_MARGIN}-->
<attribute name="NO_MARGIN" type="constexpr std::uint_fast16_t" visibility="0x04" properties="0x00">
<code>{0xFFFFU};</code>
</attribute>
</package>
<!--${QF::QF-dyn}-->
<package name="QF-dyn" stereotype="0x02" namespace="QF::">
<!--${QF::QF-dyn::poolInit}-->
<operation name="poolInit" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QF-dyn::poolInit::poolSto}-->
<parameter name="poolSto" type="void * const"/>
<!--${QF::QF-dyn::poolInit::poolSize}-->
<parameter name="poolSize" type="std::uint_fast32_t const"/>
<!--${QF::QF-dyn::poolInit::evtSize}-->
<parameter name="evtSize" type="std::uint_fast16_t const"/>
<code>std::uint_fast8_t const poolNum = priv_.maxPool_;
// see precondition{qf_dyn,200} and precondition{qf_dyn,201}
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(200, poolNum &lt; QF_MAX_EPOOL);
if (poolNum &gt; 0U) {
Q_REQUIRE_INCRIT(201,
QF_EPOOL_EVENT_SIZE_(priv_.ePool_[poolNum - 1U]) &lt; evtSize);
}
priv_.maxPool_ = poolNum + 1U; // one more pool
QF_MEM_APP();
QF_CRIT_EXIT();
// perform the port-dependent initialization of the event-pool
QF_EPOOL_INIT_(priv_.ePool_[poolNum], poolSto, poolSize, evtSize);
#ifdef Q_SPY
// generate the object-dictionary entry for the initialized pool
{
std::uint8_t obj_name[9] = &quot;EvtPool?&quot;;
obj_name[7] = static_cast&lt;std::uint8_t&gt;(
static_cast&lt;std::uint8_t&gt;('0')
+ static_cast&lt;std::uint8_t&gt;(poolNum + 1U));
QS::obj_dict_pre_(&amp;priv_.ePool_[poolNum],
reinterpret_cast&lt;char *&gt;(&amp;obj_name[0]));
}
#endif // Q_SPY</code>
</operation>
<!--${QF::QF-dyn::poolGetMaxBlockSize}-->
<operation name="poolGetMaxBlockSize" type="std::uint_fast16_t" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
std::uint_fast16_t const max_size =
QF_EPOOL_EVENT_SIZE_(priv_.ePool_[priv_.maxPool_ - 1U]);
QF_MEM_APP();
QF_CRIT_EXIT();
return max_size;</code>
</operation>
<!--${QF::QF-dyn::getPoolMin}-->
<operation name="getPoolMin" type="std::uint_fast16_t" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QF-dyn::getPoolMin::poolNum}-->
<parameter name="poolNum" type="std::uint_fast8_t const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(400, (poolNum &lt;= QF_MAX_EPOOL)
&amp;&amp; (0U &lt; poolNum) &amp;&amp; (poolNum &lt;= priv_.maxPool_));
std::uint_fast16_t const min = static_cast&lt;std::uint_fast16_t&gt;(
priv_.ePool_[poolNum - 1U].getNMin());
QF_MEM_APP();
QF_CRIT_EXIT();
return min;</code>
</operation>
<!--${QF::QF-dyn::newX_}-->
<operation name="newX_" type="QEvt *" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QF-dyn::newX_::evtSize}-->
<parameter name="evtSize" type="std::uint_fast16_t const"/>
<!--${QF::QF-dyn::newX_::margin}-->
<parameter name="margin" type="std::uint_fast16_t const"/>
<!--${QF::QF-dyn::newX_::sig}-->
<parameter name="sig" type="enum_t const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
// find the pool id that fits the requested event size...
std::uint_fast8_t poolNum = 0U; // zero-based poolNum initially
for (; poolNum &lt; priv_.maxPool_; ++poolNum) {
if (evtSize &lt;= QF_EPOOL_EVENT_SIZE_(priv_.ePool_[poolNum])) {
break;
}
}
// precondition:
// - cannot run out of registered pools
Q_REQUIRE_INCRIT(300, poolNum &lt; priv_.maxPool_);
++poolNum; // convert to 1-based poolNum
QF_MEM_APP();
QF_CRIT_EXIT();
// get event e (port-dependent)...
QEvt *e;
#ifdef Q_SPY
QF_EPOOL_GET_(priv_.ePool_[poolNum - 1U], e,
((margin != NO_MARGIN) ? margin : 0U),
static_cast&lt;std::uint_fast8_t&gt;(QS_EP_ID) + poolNum);
#else
QF_EPOOL_GET_(priv_.ePool_[poolNum - 1U], e,
((margin != NO_MARGIN) ? margin : 0U), 0U);
#endif
if (e != nullptr) { // was e allocated correctly?
e-&gt;sig = static_cast&lt;QSignal&gt;(sig); // set the signal
e-&gt;refCtr_ = 0U; // initialize the reference counter to 0
e-&gt;evtTag_ = static_cast&lt;std::uint8_t&gt;(QEvt::MARKER | poolNum);
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QF_NEW,
static_cast&lt;std::uint_fast8_t&gt;(QS_EP_ID) + poolNum)
QS_TIME_PRE_(); // timestamp
QS_EVS_PRE_(evtSize); // the size of the event
QS_SIG_PRE_(sig); // the signal of the event
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();
}
else { // event was not allocated
QF_CRIT_ENTRY();
// This assertion means that the event allocation failed,
// and this failure cannot be tolerated. The most frequent
// reason is an event leak in the application.
Q_ASSERT_INCRIT(320, margin != NO_MARGIN);
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QF_NEW_ATTEMPT,
static_cast&lt;std::uint_fast8_t&gt;(QS_EP_ID) + poolNum)
QS_TIME_PRE_(); // timestamp
QS_EVS_PRE_(evtSize); // the size of the event
QS_SIG_PRE_(sig); // the signal of the event
QS_END_PRE_()
QS_MEM_APP();
QF_CRIT_EXIT();
}
// the returned event e is guaranteed to be valid (not NULL)
// if we can't tolerate failed allocation
return e;</code>
</operation>
<!--${QF::QF-dyn::gc}-->
<operation name="gc" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QF-dyn::gc::e}-->
<parameter name="e" type="QEvt const * const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_INVARIANT_INCRIT(402, QEvt::verify_(e));
std::uint_fast8_t const poolNum = e-&gt;getPoolNum_();
if (poolNum != 0U) { // is it a pool event (mutable)?
QF_MEM_SYS();
if (e-&gt;refCtr_ &gt; 1U) { // isn't this the last reference?
QS_BEGIN_PRE_(QS_QF_GC_ATTEMPT,
static_cast&lt;std::uint_fast8_t&gt;(QS_EP_ID) + poolNum)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_2U8_PRE_(poolNum, e-&gt;refCtr_); // poolNum &amp; refCtr
QS_END_PRE_()
QEvt_refCtr_dec_(e); // decrement the ref counter
QF_MEM_APP();
QF_CRIT_EXIT();
}
else { // this is the last reference to this event, recycle it
QS_BEGIN_PRE_(QS_QF_GC,
static_cast&lt;std::uint_fast8_t&gt;(QS_EP_ID) + poolNum)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_2U8_PRE_(poolNum, e-&gt;refCtr_); // poolNum &amp; refCtr
QS_END_PRE_()
// pool number must be in range
Q_ASSERT_INCRIT(410, (poolNum &lt;= priv_.maxPool_)
&amp;&amp; (poolNum &lt;= QF_MAX_EPOOL));
QF_MEM_APP();
QF_CRIT_EXIT();
// NOTE: casting 'const' away is legit because it's a pool event
#ifdef Q_SPY
QF_EPOOL_PUT_(priv_.ePool_[poolNum - 1U],
QF_CONST_CAST_(QEvt*, e),
static_cast&lt;std::uint_fast8_t&gt;(QS_EP_ID) + poolNum);
#else
QF_EPOOL_PUT_(priv_.ePool_[poolNum - 1U],
QF_CONST_CAST_(QEvt*, e), 0U);
#endif
}
}
else {
QF_CRIT_EXIT();
}</code>
</operation>
<!--${QF::QF-dyn::newRef_}-->
<operation name="newRef_" type="QEvt const *" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QF-dyn::newRef_::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QF::QF-dyn::newRef_::evtRef}-->
<parameter name="evtRef" type="QEvt const * const"/>
<code>#ifdef Q_UNSAFE
Q_UNUSED_PAR(evtRef);
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_INVARIANT_INCRIT(502, QEvt::verify_(e));
std::uint_fast8_t const poolNum = e-&gt;getPoolNum_();
Q_REQUIRE_INCRIT(500, (poolNum != 0U)
&amp;&amp; (evtRef == nullptr));
QEvt_refCtr_inc_(e); // increments the ref counter
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QF_NEW_REF,
static_cast&lt;std::uint_fast8_t&gt;(QS_EP_ID) + poolNum)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_2U8_PRE_(poolNum, e-&gt;refCtr_); // poolNum &amp; refCtr
QS_END_PRE_()
QS_MEM_APP();
QF_CRIT_EXIT();
return e;</code>
</operation>
<!--${QF::QF-dyn::deleteRef_}-->
<operation name="deleteRef_" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QF-dyn::deleteRef_::evtRef}-->
<parameter name="evtRef" type="QEvt const * const"/>
<code>QEvt const * const e = evtRef;
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_INVARIANT_INCRIT(602, QEvt::verify_(e));
#ifdef Q_SPY
std::uint_fast8_t const poolNum = e-&gt;getPoolNum_();
#endif
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QF_DELETE_REF,
static_cast&lt;std::uint_fast8_t&gt;(QS_EP_ID) + poolNum)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_2U8_PRE_(poolNum, e-&gt;refCtr_); // poolNum &amp; refCtr
QS_END_PRE_()
QS_MEM_APP();
QF_CRIT_EXIT();
#if (QF_MAX_EPOOL &gt; 0U)
gc(evtRef); // recycle the referenced event
#endif</code>
</operation>
<!--${QF::QF-dyn::newXfromISR_}-->
<operation name="newXfromISR_?def QF_ISR_API" type="QEvt *" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QF-dyn::newXfromISR_::evtSize}-->
<parameter name="evtSize" type="std::uint_fast16_t const"/>
<!--${QF::QF-dyn::newXfromISR_::margin}-->
<parameter name="margin" type="std::uint_fast16_t const"/>
<!--${QF::QF-dyn::newXfromISR_::sig}-->
<parameter name="sig" type="enum_t const"/>
</operation>
<!--${QF::QF-dyn::gcFromISR}-->
<operation name="gcFromISR?def QF_ISR_API" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QF-dyn::gcFromISR::e}-->
<parameter name="e" type="QEvt const *"/>
</operation>
</package>
</package>
<!--${QF-extern-C}-->
<package name="QF-extern-C" stereotype="0x02">
<!--${QF-extern-C::QF_onContextSw}-->
<operation name="QF_onContextSw?def QF_ON_CONTEXT_SW" type="void" visibility="0x00" properties="0x00">
<!--${QF-extern-C::QF_onContextSw::prev}-->
<parameter name="prev" type="QP::QActive *"/>
<!--${QF-extern-C::QF_onContextSw::next}-->
<parameter name="next" type="QP::QActive *"/>
</operation>
</package>
<!--${QF-macros}-->
<package name="QF-macros" stereotype="0x02">
<!--${QF-macros::Q_PRIO}-->
<operation name="Q_PRIO" type="QP::QPrioSpec" visibility="0x03" properties="0x02">
<!--${QF-macros::Q_PRIO::prio_}-->
<parameter name="prio_" type="std::uint8_t"/>
<!--${QF-macros::Q_PRIO::pthre_}-->
<parameter name="pthre_" type="std::uint8_t"/>
<code>\
(static_cast&lt;QP::QPrioSpec&gt;((prio_) | (pthre_) &lt;&lt; 8U))</code>
</operation>
<!--${QF-macros::Q_NEW}-->
<operation name="Q_NEW?ndef QEVT_DYN_CTOR" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::Q_NEW::evtT_}-->
<parameter name="evtT_" type="&lt;event class&gt;"/>
<!--${QF-macros::Q_NEW::sig_}-->
<parameter name="sig_" type="QP::QSignal"/>
<code>(static_cast&lt;evtT_ *&gt;( \
QP::QF::newX_(sizeof(evtT_), QP::QF::NO_MARGIN, (sig_))))</code>
</operation>
<!--${QF-macros::Q_NEW}-->
<operation name="Q_NEW?def QEVT_DYN_CTOR" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::Q_NEW::evtT_}-->
<parameter name="evtT_" type="&lt;event class&gt;"/>
<!--${QF-macros::Q_NEW::sig_}-->
<parameter name="sig_" type="QP::QSignal"/>
<!--${QF-macros::Q_NEW::...}-->
<parameter name="..." type="__VA_ARGS__"/>
<code>( static_cast&lt;evtT_ *&gt;( \
QP::QF::newX_(sizeof(evtT_), QP::QF::NO_MARGIN, (sig_)))-&gt;ctor(__VA_ARGS__))</code>
</operation>
<!--${QF-macros::Q_NEW_X}-->
<operation name="Q_NEW_X?ndef QEVT_DYN_CTOR" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::Q_NEW_X::evtT_}-->
<parameter name="evtT_" type="&lt;event class&gt;"/>
<!--${QF-macros::Q_NEW_X::margin_}-->
<parameter name="margin_" type="std::uint16_t"/>
<!--${QF-macros::Q_NEW_X::sig_}-->
<parameter name="sig_" type="QP::QSignal"/>
<code>(static_cast&lt;evtT_ *&gt;( \
QP::QF::newX_(sizeof(evtT_), (margin_), (sig_))))</code>
</operation>
<!--${QF-macros::Q_NEW_X}-->
<operation name="Q_NEW_X?def QEVT_DYN_CTOR" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::Q_NEW_X::evtT_}-->
<parameter name="evtT_" type="&lt;event class&gt;"/>
<!--${QF-macros::Q_NEW_X::margin_}-->
<parameter name="margin_" type="std::uint16_t"/>
<!--${QF-macros::Q_NEW_X::sig_}-->
<parameter name="sig_" type="QP::QSignal"/>
<!--${QF-macros::Q_NEW_X::...}-->
<parameter name="..." type="__VA_ARGS__"/>
<code>( static_cast&lt;evtT_ *&gt;( \
QP::QF::newX_(sizeof(evtT_), (margin_), (sig_)))-&gt;ctor(__VA_ARGS__))</code>
</operation>
<!--${QF-macros::Q_NEW_REF}-->
<operation name="Q_NEW_REF" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::Q_NEW_REF::evtRef_}-->
<parameter name="evtRef_" type="&lt;event class&gt;"/>
<!--${QF-macros::Q_NEW_REF::evtT_}-->
<parameter name="evtT_" type="&lt;event class&gt;"/>
<code>\
((evtRef_) = static_cast&lt;evtT_ const *&gt;(QP::QF::newRef_(e, (evtRef_))))</code>
</operation>
<!--${QF-macros::Q_DELETE_REF}-->
<operation name="Q_DELETE_REF" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::Q_DELETE_REF::evtRef_}-->
<parameter name="evtRef_" type="&lt;event class&gt;"/>
<code>do { \
QP::QF::deleteRef_((evtRef_)); \
(evtRef_) = 0U; \
} while (false)</code>
</operation>
<!--${QF-macros::PUBLISH}-->
<operation name="PUBLISH?def Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::PUBLISH::e_}-->
<parameter name="e_" type="QP::QEvt const *"/>
<!--${QF-macros::PUBLISH::sender_}-->
<parameter name="sender_" type="&lt;void const *&gt;"/>
<code>\
publish_((e_), (sender_), (sender_)-&gt;getPrio())</code>
</operation>
<!--${QF-macros::PUBLISH}-->
<operation name="PUBLISH?ndef Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::PUBLISH::e_}-->
<parameter name="e_" type="QP::QEvt const *"/>
<!--${QF-macros::PUBLISH::dummy}-->
<parameter name="dummy" type=""/>
<code>publish_((e_), nullptr, 0U)</code>
</operation>
<!--${QF-macros::POST}-->
<operation name="POST?def Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::POST::e_}-->
<parameter name="e_" type="QP::QEvt const *"/>
<!--${QF-macros::POST::sender_}-->
<parameter name="sender_" type="&lt;sender *&gt;"/>
<code>post_((e_), QP::QF::NO_MARGIN, (sender_))</code>
</operation>
<!--${QF-macros::POST}-->
<operation name="POST?ndef Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::POST::e_}-->
<parameter name="e_" type="QP::QEvt const *"/>
<!--${QF-macros::POST::dummy}-->
<parameter name="dummy" type=""/>
<code>post_((e_), QP::QF::NO_MARGIN, nullptr)</code>
</operation>
<!--${QF-macros::POST_X}-->
<operation name="POST_X?def Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::POST_X::e_}-->
<parameter name="e_" type="QP::QEvt const *"/>
<!--${QF-macros::POST_X::margin_}-->
<parameter name="margin_" type="std::uint16_t"/>
<!--${QF-macros::POST_X::sender_}-->
<parameter name="sender_" type="&lt;sender *&gt;"/>
<code>\
post_((e_), (margin_), (sender_))</code>
</operation>
<!--${QF-macros::POST_X}-->
<operation name="POST_X?ndef Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::POST_X::e_}-->
<parameter name="e_" type="QP::QEvt const *"/>
<!--${QF-macros::POST_X::margin_}-->
<parameter name="margin_" type="std::uint16_t"/>
<!--${QF-macros::POST_X::dummy}-->
<parameter name="dummy" type=""/>
<code>post_((e_), (margin_), nullptr)</code>
</operation>
<!--${QF-macros::TICK_X}-->
<operation name="TICK_X?def Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::TICK_X::tickRate_}-->
<parameter name="tickRate_" type="std::uint_fast8_t const"/>
<!--${QF-macros::TICK_X::sender_}-->
<parameter name="sender_" type="&lt;void const *&gt;"/>
<code>tick((tickRate_), (sender_))</code>
</operation>
<!--${QF-macros::TICK_X}-->
<operation name="TICK_X?ndef Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::TICK_X::tickRate_}-->
<parameter name="tickRate_" type="std::uint_fast8_t const"/>
<!--${QF-macros::TICK_X::dummy}-->
<parameter name="dummy" type=""/>
<code>tick((tickRate_), nullptr)</code>
</operation>
<!--${QF-macros::TICK}-->
<operation name="TICK" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::TICK::sender_}-->
<parameter name="sender_" type="&lt;sender *&gt;"/>
<code>TICK_X(0U, (sender_))</code>
</operation>
<!--${QF-macros::TRIG}-->
<operation name="TRIG?def Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::TRIG::sender_}-->
<parameter name="sender_" type="&lt;void const *&gt;"/>
<code>trig_((sender_))</code>
</operation>
<!--${QF-macros::TRIG}-->
<operation name="TRIG?ndef Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::TRIG::sender_}-->
<parameter name="sender_" type="&lt;void const *&gt;"/>
<code>trig_(nullptr)</code>
</operation>
<!--${QF-macros::QF_CRIT_EXIT_NOP}-->
<operation name="QF_CRIT_EXIT_NOP?ndef QF_CRIT_EXIT_NOP" type="void" visibility="0x03" properties="0x00">
<code>(static_cast&lt;void&gt;(0))</code>
</operation>
<!--${QF-macros::QF_MEM_SYS}-->
<operation name="QF_MEM_SYS?ndef QF_MEM_SYS" type="void" visibility="0x03" properties="0x00">
<code>(static_cast&lt;void&gt;(0))</code>
</operation>
<!--${QF-macros::QF_MEM_APP}-->
<operation name="QF_MEM_APP?ndef QF_MEM_APP" type="void" visibility="0x03" properties="0x00">
<code>(static_cast&lt;void&gt;(0))</code>
</operation>
</package>
<!--${QF_EPOOL-impl}-->
<package name="QF_EPOOL-impl" stereotype="0x02">
<!--${QF_EPOOL-impl::QF_EPOOL_TYPE_}-->
<attribute name="QF_EPOOL_TYPE_" type="" visibility="0x03" properties="0x00">
<documentation>Native QF event pool</documentation>
<code>QMPool</code>
</attribute>
<!--${QF_EPOOL-impl::QF_EPOOL_INIT_}-->
<operation name="QF_EPOOL_INIT_" type="" visibility="0x03" properties="0x00">
<documentation>Native QF event pool initialization</documentation>
<!--${QF_EPOOL-impl::QF_EPOOL_INIT_::p_}-->
<parameter name="p_" type="QMPool *"/>
<!--${QF_EPOOL-impl::QF_EPOOL_INIT_::poolSto_}-->
<parameter name="poolSto_" type="void *"/>
<!--${QF_EPOOL-impl::QF_EPOOL_INIT_::poolSize_}-->
<parameter name="poolSize_" type="std::uint_fast32_t"/>
<!--${QF_EPOOL-impl::QF_EPOOL_INIT_::evtSize_}-->
<parameter name="evtSize_" type="std::uint_fast16_t"/>
<code>\
(p_).init((poolSto_), (poolSize_), (evtSize_))</code>
</operation>
<!--${QF_EPOOL-impl::QF_EPOOL_EVENT_SIZE_}-->
<operation name="QF_EPOOL_EVENT_SIZE_" type="" visibility="0x03" properties="0x00">
<documentation>Native QF event pool event-size getter</documentation>
<!--${QF_EPOOL-impl::QF_EPOOL_EVENT_S~::p_}-->
<parameter name="p_" type="QMPool const *"/>
<code>((p_).getBlockSize())</code>
</operation>
<!--${QF_EPOOL-impl::QF_EPOOL_GET_}-->
<operation name="QF_EPOOL_GET_" type="" visibility="0x03" properties="0x00">
<documentation>Native QF event pool get-event</documentation>
<!--${QF_EPOOL-impl::QF_EPOOL_GET_::p_}-->
<parameter name="p_" type="QMPool *"/>
<!--${QF_EPOOL-impl::QF_EPOOL_GET_::e_}-->
<parameter name="e_" type="QEvt *"/>
<!--${QF_EPOOL-impl::QF_EPOOL_GET_::m_}-->
<parameter name="m_" type="std::uint_fast16_t"/>
<!--${QF_EPOOL-impl::QF_EPOOL_GET_::qsId_}-->
<parameter name="qsId_" type="std::uint8_t"/>
<code>\
((e_) = static_cast&lt;QEvt *&gt;((p_).get((m_), (qsId_))))</code>
</operation>
<!--${QF_EPOOL-impl::QF_EPOOL_PUT_}-->
<operation name="QF_EPOOL_PUT_" type="" visibility="0x03" properties="0x00">
<documentation>Native QF event pool put-event</documentation>
<!--${QF_EPOOL-impl::QF_EPOOL_PUT_::p_}-->
<parameter name="p_" type="QMPool *"/>
<!--${QF_EPOOL-impl::QF_EPOOL_PUT_::e_}-->
<parameter name="e_" type="QEvt *"/>
<!--${QF_EPOOL-impl::QF_EPOOL_PUT_::qsId_}-->
<parameter name="qsId_" type="std::uint8_t"/>
<code>((p_).put((e_), (qsId_)))</code>
</operation>
</package>
<!--${QV}-->
<package name="QV" stereotype="0x05" namespace="QP::">
<!--${QV::QV-base}-->
<package name="QV-base" stereotype="0x02" namespace="QV::">
<!--${QV::QV-base::Attr}-->
<class name="Attr">
<!--${QV::QV-base::Attr::readySet}-->
<attribute name="readySet" type="QPSet" visibility="0x00" properties="0x00"/>
<!--${QV::QV-base::Attr::schedCeil}-->
<attribute name="schedCeil" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QV::QV-base::Attr::readySet_dis}-->
<attribute name="readySet_dis?ndef Q_UNSAFE" type="QPSet" visibility="0x00" properties="0x00"/>
<!--${QV::QV-base::Attr::schedCeil_dis}-->
<attribute name="schedCeil_dis?ndef Q_UNSAFE" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
</class>
<!--${QV::QV-base::priv_}-->
<attribute name="priv_" type="QV::Attr" visibility="0x00" properties="0x01"/>
<!--${QV::QV-base::schedDisable}-->
<operation name="schedDisable" type="void" visibility="0x00" properties="0x01">
<!--${QV::QV-base::schedDisable::ceiling}-->
<parameter name="ceiling" type="std::uint_fast8_t const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_INVARIANT_INCRIT(102, priv_.schedCeil
== static_cast&lt;std::uint_fast8_t&gt;(~priv_.schedCeil_dis));
if (ceiling &gt; priv_.schedCeil) { // raising the scheduler ceiling?
QS_BEGIN_PRE_(QS_SCHED_LOCK, 0U)
QS_TIME_PRE_(); // timestamp
// the previous sched ceiling &amp; new sched ceiling
QS_2U8_PRE_(static_cast&lt;std::uint8_t&gt;(priv_.schedCeil),
static_cast&lt;std::uint8_t&gt;(ceiling));
QS_END_PRE_()
priv_.schedCeil = ceiling;
#ifndef Q_UNSAFE
priv_.schedCeil_dis = static_cast&lt;std::uint_fast8_t&gt;(~ceiling);
#endif
}
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QV::QV-base::schedEnable}-->
<operation name="schedEnable" type="void" visibility="0x00" properties="0x01">
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_INVARIANT_INCRIT(202, priv_.schedCeil
== static_cast&lt;std::uint_fast8_t&gt;(~priv_.schedCeil_dis));
if (priv_.schedCeil != 0U) { // actually enabling the scheduler?
QS_BEGIN_PRE_(QS_SCHED_UNLOCK, 0U)
QS_TIME_PRE_(); // timestamp
// current sched ceiling (old), previous sched ceiling (new)
QS_2U8_PRE_(static_cast&lt;std::uint8_t&gt;(priv_.schedCeil), 0U);
QS_END_PRE_()
priv_.schedCeil = 0U;
#ifndef Q_UNSAFE
priv_.schedCeil_dis = ~static_cast&lt;std::uint_fast8_t&gt;(0U);
#endif
}
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QV::QV-base::onIdle}-->
<operation name="onIdle" type="void" visibility="0x00" properties="0x01"/>
</package>
<!--${QV::QF-cust}-->
<package name="QF-cust" stereotype="0x02" namespace="QF::">
<!--${QV::QF-cust::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x01">
<code>bzero_(&amp;QF::priv_, sizeof(QF::priv_));
bzero_(&amp;QV::priv_, sizeof(QV::priv_));
bzero_(&amp;QActive::registry_[0], sizeof(QActive::registry_));
#ifndef Q_UNSAFE
QV::priv_.readySet.update_(&amp;QV::priv_.readySet_dis);
QV::priv_.schedCeil_dis = ~static_cast&lt;std::uint_fast8_t&gt;(0U);
#endif
#ifdef QV_INIT
QV_INIT(); // port-specific initialization of the QV kernel
#endif</code>
</operation>
<!--${QV::QF-cust::stop}-->
<operation name="stop" type="void" visibility="0x00" properties="0x01">
<code>onCleanup(); // cleanup callback
// nothing else to do for the QV kernel</code>
</operation>
<!--${QV::QF-cust::run}-->
<operation name="run" type="int_t" visibility="0x00" properties="0x01">
<code>#ifdef Q_SPY
// produce the QS_QF_RUN trace record
QF_INT_DISABLE();
QF_MEM_SYS();
QS::beginRec_(QS_REC_NUM_(QS_QF_RUN));
QS::endRec_();
QF_MEM_APP();
QF_INT_ENABLE();
#endif // Q_SPY
onStartup(); // application-specific startup callback
QF_INT_DISABLE();
QF_MEM_SYS();
#ifdef QV_START
QV_START(); // port-specific startup of the QV kernel
#endif
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
std::uint_fast8_t pprev = 0U; // previous prio.
#endif
for (;;) { // QV event loop...
// check internal integrity (duplicate inverse storage)
Q_INVARIANT_INCRIT(302,
QV::priv_.readySet.verify_(&amp;QV::priv_.readySet_dis));
// check internal integrity (duplicate inverse storage)
Q_INVARIANT_INCRIT(303, QV::priv_.schedCeil
== static_cast&lt;std::uint_fast8_t&gt;(~QV::priv_.schedCeil_dis));
// find the maximum prio. AO ready to run
std::uint_fast8_t const p = (QV::priv_.readySet.notEmpty()
? QV::priv_.readySet.findMax()
: 0U);
if (p &gt; QV::priv_.schedCeil) { // is it above the sched ceiling?
QActive * const a = QActive::registry_[p];
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
QS_BEGIN_PRE_(QS_SCHED_NEXT, p)
QS_TIME_PRE_(); // timestamp
QS_2U8_PRE_(static_cast&lt;std::uint8_t&gt;(p),
static_cast&lt;std::uint8_t&gt;(pprev));
QS_END_PRE_()
#ifdef QF_ON_CONTEXT_SW
QF_onContextSw(((pprev != 0U)
? QActive::registry_[pprev]
: nullptr), a);
#endif // QF_ON_CONTEXT_SW
pprev = p; // update previous prio.
#endif // (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
QF_MEM_APP();
QF_INT_ENABLE();
QEvt const * const e = a-&gt;get_();
// NOTE QActive::get_() performs QF_MEM_APP() before return
// dispatch event (virtual call)
a-&gt;dispatch(e, a-&gt;getPrio());
#if (QF_MAX_EPOOL &gt; 0U)
gc(e);
#endif
QF_INT_DISABLE();
QF_MEM_SYS();
if (a-&gt;getEQueue().isEmpty()) { // empty queue?
QV::priv_.readySet.remove(p);
#ifndef Q_UNSAFE
QV::priv_.readySet.update_(&amp;QV::priv_.readySet_dis);
#endif
}
}
else { // no AO ready to run --&gt; idle
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
if (pprev != 0U) {
QS_BEGIN_PRE_(QS_SCHED_IDLE, pprev)
QS_TIME_PRE_(); // timestamp
QS_U8_PRE_(static_cast&lt;std::uint8_t&gt;(pprev));
QS_END_PRE_()
#ifdef QF_ON_CONTEXT_SW
QF_onContextSw(QActive::registry_[pprev], nullptr);
#endif // QF_ON_CONTEXT_SW
pprev = 0U; // update previous prio
}
#endif // (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
QF_MEM_APP();
// QV::onIdle() must be called with interrupts DISABLED
// because the determination of the idle condition (all event
// queues empty) can change at any time by an interrupt posting
// events to a queue.
//
// NOTE: QV::onIdle() MUST enable interrupts internally,
// ideally at the same time as putting the CPU into a power-
// saving mode.
QV::onIdle();
QF_INT_DISABLE();
QF_MEM_SYS();
}
}
#ifdef __GNUC__ // GNU compiler?
return 0;
#endif</code>
</operation>
</package>
<!--${QV::QActive}-->
<class name="QActive" superclass="qpcpp::QAsm">
<!--${QV::QActive::start}-->
<operation name="start" type="void" visibility="0x00" properties="0x04">
<!--${QV::QActive::start::prioSpec}-->
<parameter name="prioSpec" type="QPrioSpec const"/>
<!--${QV::QActive::start::qSto}-->
<parameter name="qSto" type="QEvt const * * const"/>
<!--${QV::QActive::start::qLen}-->
<parameter name="qLen" type="std::uint_fast16_t const"/>
<!--${QV::QActive::start::stkSto}-->
<parameter name="stkSto" type="void * const"/>
<!--${QV::QActive::start::stkSize}-->
<parameter name="stkSize" type="std::uint_fast16_t const"/>
<!--${QV::QActive::start::par}-->
<parameter name="par" type="void const * const"/>
<code>Q_UNUSED_PAR(stkSto); // not needed in QV
Q_UNUSED_PAR(stkSize); // not needed in QV
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(300, stkSto == nullptr);
QF_CRIT_EXIT();
m_prio = static_cast&lt;std::uint8_t&gt;(prioSpec &amp; 0xFFU); // QF-prio.
m_pthre = 0U; // not used
register_(); // make QF aware of this AO
m_eQueue.init(qSto, qLen); // initialize QEQueue of this AO
this-&gt;init(par, m_prio); // take the top-most initial tran. (virtual)
QS_FLUSH(); // flush the trace buffer to the host</code>
</operation>
</class>
</package>
<!--${QV-impl}-->
<package name="QV-impl" stereotype="0x02">
<!--${QV-impl::QF_SCHED_STAT_}-->
<attribute name="QF_SCHED_STAT_" type="" visibility="0x03" properties="0x00"/>
<!--${QV-impl::QF_SCHED_LOCK_}-->
<operation name="QF_SCHED_LOCK_" type="" visibility="0x03" properties="0x00">
<!--${QV-impl::QF_SCHED_LOCK_::dummy}-->
<parameter name="dummy" type=""/>
<code>(static_cast&lt;void&gt;(0))</code>
</operation>
<!--${QV-impl::QF_SCHED_UNLOCK_}-->
<operation name="QF_SCHED_UNLOCK_" type="" visibility="0x03" properties="0x00">
<code>(static_cast&lt;void&gt;(0))</code>
</operation>
<!--${QV-impl::QACTIVE_EQUEUE_WAIT_}-->
<operation name="QACTIVE_EQUEUE_WAIT_" type="" visibility="0x03" properties="0x00">
<!--${QV-impl::QACTIVE_EQUEUE_W~::me_}-->
<parameter name="me_" type="QP::QActive *"/>
<code>\
Q_ASSERT_INCRIT(310, (me_)-&gt;m_eQueue.m_frontEvt != nullptr)</code>
</operation>
<!--${QV-impl::QACTIVE_EQUEUE_SIGNAL_}-->
<operation name="QACTIVE_EQUEUE_SIGNAL_?ndef Q_UNSAFE" type="" visibility="0x03" properties="0x00">
<!--${QV-impl::QACTIVE_EQUEUE_S~::me_}-->
<parameter name="me_" type="QP::QActive *"/>
<code>\
QV::priv_.readySet.insert((me_)-&gt;m_prio); \
QV::priv_.readySet.update_(&amp;QV::priv_.readySet_dis)</code>
</operation>
<!--${QV-impl::QACTIVE_EQUEUE_SIGNAL_}-->
<operation name="QACTIVE_EQUEUE_SIGNAL_?def Q_UNSAFE" type="" visibility="0x03" properties="0x00">
<!--${QV-impl::QACTIVE_EQUEUE_S~::me_}-->
<parameter name="me_" type="QP::QActive *"/>
<code>\
(QV::priv_.readySet.insert((me_)-&gt;m_prio))</code>
</operation>
</package>
<!--${QK}-->
<package name="QK" stereotype="0x05" namespace="QP::">
<!--${QK::QSchedStatus}-->
<attribute name="QSchedStatus" type="using" visibility="0x04" properties="0x00">
<code>= std::uint_fast8_t;</code>
</attribute>
<!--${QK::QK-base}-->
<package name="QK-base" stereotype="0x02" namespace="QK::">
<!--${QK::QK-base::schedLock}-->
<operation name="schedLock" type="QSchedStatus" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QK::QK-base::schedLock::ceiling}-->
<parameter name="ceiling" type="std::uint_fast8_t const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(100, !QK_ISR_CONTEXT_());
Q_INVARIANT_INCRIT(102, QK_priv_.lockCeil
== static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.lockCeil_dis));
// first store the previous lock prio
QSchedStatus stat;
if (ceiling &gt; QK_priv_.lockCeil) { // raising the lock ceiling?
QS_BEGIN_PRE_(QS_SCHED_LOCK, QK_priv_.actPrio)
QS_TIME_PRE_(); // timestamp
// the previous lock ceiling &amp; new lock ceiling
QS_2U8_PRE_(static_cast&lt;std::uint8_t&gt;(QK_priv_.lockCeil),
static_cast&lt;std::uint8_t&gt;(ceiling));
QS_END_PRE_()
// previous status of the lock
stat = static_cast&lt;QSchedStatus&gt;(QK_priv_.lockCeil);
// new status of the lock
QK_priv_.lockCeil = ceiling;
#ifndef Q_UNSAFE
QK_priv_.lockCeil_dis = static_cast&lt;std::uint_fast8_t&gt;(~ceiling);
#endif
}
else {
stat = 0xFFU; // scheduler not locked
}
QF_MEM_APP();
QF_CRIT_EXIT();
return stat; // return the status to be saved in a stack variable</code>
</operation>
<!--${QK::QK-base::schedUnlock}-->
<operation name="schedUnlock" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QK::QK-base::schedUnlock::prevCeil}-->
<parameter name="prevCeil" type="QSchedStatus const"/>
<code>// has the scheduler been actually locked by the last QK::schedLock()?
if (prevCeil != 0xFFU) {
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_INVARIANT_INCRIT(202, QK_priv_.lockCeil
== static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.lockCeil_dis));
Q_REQUIRE_INCRIT(210, (!QK_ISR_CONTEXT_())
&amp;&amp; (QK_priv_.lockCeil &gt; prevCeil));
QS_BEGIN_PRE_(QS_SCHED_UNLOCK, QK_priv_.actPrio)
QS_TIME_PRE_(); // timestamp
// current lock ceiling (old), previous lock ceiling (new)
QS_2U8_PRE_(static_cast&lt;std::uint8_t&gt;(QK_priv_.lockCeil),
static_cast&lt;std::uint8_t&gt;(prevCeil));
QS_END_PRE_()
// restore the previous lock ceiling
QK_priv_.lockCeil = prevCeil;
#ifndef Q_UNSAFE
QK_priv_.lockCeil_dis = static_cast&lt;std::uint_fast8_t&gt;(~prevCeil);
#endif
// find if any AOs should be run after unlocking the scheduler
if (QK_sched_() != 0U) { // preemption needed?
QK_activate_(); // activate any unlocked AOs
}
QF_MEM_APP();
QF_CRIT_EXIT();
}</code>
</operation>
<!--${QK::QK-base::onIdle}-->
<operation name="onIdle" type="void" visibility="0x00" properties="0x01"/>
</package>
<!--${QK::QF-cust}-->
<package name="QF-cust" stereotype="0x02" namespace="QF::">
<!--${QK::QF-cust::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x01">
<code>bzero_(&amp;QF::priv_, sizeof(QF::priv_));
bzero_(&amp;QK_priv_, sizeof(QK_priv_));
bzero_(&amp;QActive::registry_[0], sizeof(QActive::registry_));
// setup the QK scheduler as initially locked and not running
QK_priv_.lockCeil = (QF_MAX_ACTIVE + 1U); // scheduler locked
#ifndef Q_UNSAFE
QK_priv_.readySet.update_(&amp;QK_priv_.readySet_dis);
QK_priv_.actPrio_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.actPrio);
QK_priv_.nextPrio_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.nextPrio);
QK_priv_.actThre_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.actThre);
QK_priv_.lockCeil_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.lockCeil);
#endif
#ifdef QK_INIT
QK_INIT(); // port-specific initialization of the QK kernel
#endif</code>
</operation>
<!--${QK::QF-cust::stop}-->
<operation name="stop" type="void" visibility="0x00" properties="0x01">
<code>onCleanup(); // cleanup callback
// nothing else to do for the QK preemptive kernel</code>
</operation>
<!--${QK::QF-cust::run}-->
<operation name="run" type="int_t" visibility="0x00" properties="0x01">
<code>#ifdef Q_SPY
// produce the QS_QF_RUN trace record
QF_INT_DISABLE();
QF_MEM_SYS();
QS::beginRec_(QS_REC_NUM_(QS_QF_RUN));
QS::endRec_();
QF_MEM_APP();
QF_INT_ENABLE();
#endif // Q_SPY
onStartup(); // application-specific startup callback
QF_INT_DISABLE();
QF_MEM_SYS();
#ifdef QK_START
QK_START(); // port-specific startup of the QK kernel
#endif
QK_priv_.lockCeil = 0U; // unlock the QK scheduler
#ifndef Q_UNSAFE
QK_priv_.lockCeil_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.lockCeil);
#endif
// activate AOs to process events posted so far
if (QK_sched_() != 0U) {
QK_activate_();
}
QF_MEM_APP();
QF_INT_ENABLE();
for (;;) { // QK idle loop...
QK::onIdle(); // application-specific QK on-idle callback
}
#ifdef __GNUC__ // GNU compiler?
return 0;
#endif</code>
</operation>
</package>
<!--${QK::QActive}-->
<class name="QActive" superclass="QEP::QAsm">
<!--${QK::QActive::start}-->
<operation name="start" type="void" visibility="0x00" properties="0x04">
<!--${QK::QActive::start::prioSpec}-->
<parameter name="prioSpec" type="QPrioSpec const"/>
<!--${QK::QActive::start::qSto}-->
<parameter name="qSto" type="QEvt const * * const"/>
<!--${QK::QActive::start::qLen}-->
<parameter name="qLen" type="std::uint_fast16_t const"/>
<!--${QK::QActive::start::stkSto}-->
<parameter name="stkSto" type="void * const"/>
<!--${QK::QActive::start::stkSize}-->
<parameter name="stkSize" type="std::uint_fast16_t const"/>
<!--${QK::QActive::start::par}-->
<parameter name="par" type="void const * const"/>
<code>Q_UNUSED_PAR(stkSto); // not needed in QK
Q_UNUSED_PAR(stkSize); // not needed in QK
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(300, (!QK_ISR_CONTEXT_())
&amp;&amp; (stkSto == nullptr));
QF_MEM_APP();
QF_CRIT_EXIT();
m_prio = static_cast&lt;std::uint8_t&gt;(prioSpec &amp; 0xFFU); // QF-prio.
m_pthre = static_cast&lt;std::uint8_t&gt;(prioSpec &gt;&gt; 8U); // preemption-thre.
register_(); // make QF aware of this AO
m_eQueue.init(qSto, qLen); // init the built-in queue
// top-most initial tran. (virtual call)
this-&gt;init(par, m_prio);
QS_FLUSH(); // flush the trace buffer to the host
// See if this AO needs to be scheduled if QK is already running
QF_CRIT_ENTRY();
QF_MEM_SYS();
if (QK_sched_() != 0U) { // activation needed?
QK_activate_();
}
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
</class>
</package>
<!--${QK-extern-C}-->
<package name="QK-extern-C" stereotype="0x02">
<!--${QK-extern-C::QK_Attr}-->
<class name="QK_Attr">
<!--${QK-extern-C::QK_Attr::readySet}-->
<attribute name="readySet" type="QP::QPSet" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::actPrio}-->
<attribute name="actPrio" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::nextPrio}-->
<attribute name="nextPrio" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::actThre}-->
<attribute name="actThre" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::lockCeil}-->
<attribute name="lockCeil" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::intNest}-->
<attribute name="intNest" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::readySet_dis}-->
<attribute name="readySet_dis?ndef Q_UNSAFE" type="QP::QPSet" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::actPrio_dis}-->
<attribute name="actPrio_dis?ndef Q_UNSAFE" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::nextPrio_dis}-->
<attribute name="nextPrio_dis?ndef Q_UNSAFE" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::actThre_dis}-->
<attribute name="actThre_dis?ndef Q_UNSAFE" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::lockCeil_dis}-->
<attribute name="lockCeil_dis?ndef Q_UNSAFE" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
</class>
<!--${QK-extern-C::QK_priv_}-->
<attribute name="QK_priv_" type="QK_Attr" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_sched_}-->
<operation name="QK_sched_" type="std::uint_fast8_t" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>// NOTE: this function is entered with interrupts DISABLED
Q_INVARIANT_INCRIT(402,
QK_priv_.readySet.verify_(&amp;QK_priv_.readySet_dis));
std::uint_fast8_t p;
if (QK_priv_.readySet.isEmpty()) {
p = 0U; // no activation needed
}
else {
// find the highest-prio AO with non-empty event queue
p = QK_priv_.readySet.findMax();
Q_INVARIANT_INCRIT(412, QK_priv_.actThre
== static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.actThre_dis));
// is the AO's prio. below the active preemption-threshold?
if (p &lt;= QK_priv_.actThre) {
p = 0U; // no activation needed
}
else {
Q_INVARIANT_INCRIT(422, QK_priv_.lockCeil
== static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.lockCeil_dis));
// is the AO's prio. below the lock-ceiling?
if (p &lt;= QK_priv_.lockCeil) {
p = 0U; // no activation needed
}
else {
Q_INVARIANT_INCRIT(432, QK_priv_.nextPrio
== static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.nextPrio_dis));
QK_priv_.nextPrio = p; // next AO to run
#ifndef Q_UNSAFE
QK_priv_.nextPrio_dis
= static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.nextPrio);
#endif
}
}
}
return p;</code>
</operation>
<!--${QK-extern-C::QK_activate_}-->
<operation name="QK_activate_" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>// NOTE: this function is entered with interrupts DISABLED
std::uint_fast8_t const prio_in = QK_priv_.actPrio; // save initial prio.
std::uint_fast8_t p = QK_priv_.nextPrio; // next prio to run
Q_INVARIANT_INCRIT(502,
(prio_in == static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.actPrio_dis))
&amp;&amp; (p == static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.nextPrio_dis)));
Q_REQUIRE_INCRIT(510, (prio_in &lt;= QF_MAX_ACTIVE)
&amp;&amp; (0U &lt; p) &amp;&amp; (p &lt;= QF_MAX_ACTIVE));
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
std::uint_fast8_t pprev = prio_in;
#endif // QF_ON_CONTEXT_SW || Q_SPY
QK_priv_.nextPrio = 0U; // clear for the next time
#ifndef Q_UNSAFE
QK_priv_.nextPrio_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.nextPrio);
#endif
std::uint_fast8_t pthre_in;
QP::QActive *a;
if (prio_in == 0U) { // preempting the idle thread?
pthre_in = 0U;
}
else {
a = QP::QActive::registry_[prio_in];
Q_ASSERT_INCRIT(510, a != nullptr);
pthre_in = static_cast&lt;std::uint_fast8_t&gt;(a-&gt;getPThre());
Q_INVARIANT_INCRIT(511, pthre_in == static_cast&lt;std::uint_fast8_t&gt;(
~static_cast&lt;std::uint_fast8_t&gt;(a-&gt;m_pthre_dis) &amp; 0xFFU));
}
// loop until no more ready-to-run AOs of higher pthre than the initial
do {
a = QP::QActive::registry_[p]; // obtain the pointer to the AO
Q_ASSERT_INCRIT(520, a != nullptr); // the AO must be registered
std::uint_fast8_t const pthre
= static_cast&lt;std::uint_fast8_t&gt;(a-&gt;getPThre());
Q_INVARIANT_INCRIT(522, pthre == static_cast&lt;std::uint_fast8_t&gt;(
~static_cast&lt;std::uint_fast8_t&gt;(a-&gt;m_pthre_dis) &amp; 0xFFU));
// set new active prio. and preemption-threshold
QK_priv_.actPrio = p;
QK_priv_.actThre = pthre;
#ifndef Q_UNSAFE
QK_priv_.actPrio_dis = static_cast&lt;std::uint_fast8_t&gt;(~p);
QK_priv_.actThre_dis = static_cast&lt;std::uint_fast8_t&gt;(~pthre);
#endif
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
if (p != pprev) { // changing threads?
QS_BEGIN_PRE_(QP::QS_SCHED_NEXT, p)
QS_TIME_PRE_(); // timestamp
QS_2U8_PRE_(p, // prio. of the scheduled AO
pprev); // previous prio.
QS_END_PRE_()
#ifdef QF_ON_CONTEXT_SW
QF_onContextSw(QP::QActive::registry_[pprev], a);
#endif // QF_ON_CONTEXT_SW
pprev = p; // update previous prio.
}
#endif // QF_ON_CONTEXT_SW || Q_SPY
QF_MEM_APP();
QF_INT_ENABLE(); // unconditionally enable interrupts
QP::QEvt const * const e = a-&gt;get_();
// NOTE QActive_get_() performs QF_MEM_APP() before return
// dispatch event (virtual call)
a-&gt;dispatch(e, a-&gt;getPrio());
#if (QF_MAX_EPOOL &gt; 0U)
QP::QF::gc(e);
#endif
// determine the next highest-prio. AO ready to run...
QF_INT_DISABLE(); // unconditionally disable interrupts
QF_MEM_SYS();
// internal integrity check (duplicate inverse storage)
Q_INVARIANT_INCRIT(532,
QK_priv_.readySet.verify_(&amp;QK_priv_.readySet_dis));
if (a-&gt;getEQueue().isEmpty()) { // empty queue?
QK_priv_.readySet.remove(p);
#ifndef Q_UNSAFE
QK_priv_.readySet.update_(&amp;QK_priv_.readySet_dis);
#endif
}
if (QK_priv_.readySet.isEmpty()) {
p = 0U; // no activation needed
}
else {
// find new highest-prio AO ready to run...
p = QK_priv_.readySet.findMax();
// is the new prio. below the initial preemption-threshold?
if (p &lt;= pthre_in) {
p = 0U; // no activation needed
}
else {
Q_INVARIANT_INCRIT(542,
QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis);
// is the AO's prio. below the lock preemption-threshold?
if (p &lt;= QK_priv_.lockCeil) {
p = 0U; // no activation needed
}
else {
Q_ASSERT_INCRIT(550, p &lt;= QF_MAX_ACTIVE);
}
}
}
} while (p != 0U);
// restore the active prio. and preemption-threshold
QK_priv_.actPrio = prio_in;
QK_priv_.actThre = pthre_in;
#ifndef Q_UNSAFE
QK_priv_.actPrio_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.actPrio);
QK_priv_.actThre_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.actThre);
#endif
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
if (prio_in != 0U) { // resuming an active object?
a = QP::QActive::registry_[prio_in]; // pointer to preempted AO
QS_BEGIN_PRE_(QP::QS_SCHED_NEXT, prio_in)
QS_TIME_PRE_(); // timestamp
// prio. of the resumed AO, previous prio.
QS_2U8_PRE_(prio_in, pprev);
QS_END_PRE_()
}
else { // resuming prio.==0 --&gt; idle
a = nullptr; // QK idle loop
QS_BEGIN_PRE_(QP::QS_SCHED_IDLE, pprev)
QS_TIME_PRE_(); // timestamp
QS_U8_PRE_(pprev); // previous prio.
QS_END_PRE_()
}
#ifdef QF_ON_CONTEXT_SW
QF_onContextSw(QP::QActive::registry_[pprev], a);
#endif // QF_ON_CONTEXT_SW
#endif // QF_ON_CONTEXT_SW || Q_SPY</code>
</operation>
</package>
<!--${QK-impl}-->
<package name="QK-impl" stereotype="0x02">
<!--${QK-impl::QF_SCHED_STAT_}-->
<attribute name="QF_SCHED_STAT_" type="" visibility="0x03" properties="0x00">
<code>QSchedStatus lockStat_;</code>
</attribute>
<!--${QK-impl::QF_SCHED_LOCK_}-->
<operation name="QF_SCHED_LOCK_" type="" visibility="0x03" properties="0x00">
<!--${QK-impl::QF_SCHED_LOCK_::ceil_}-->
<parameter name="ceil_" type="std::uint_fast8_t"/>
<code>do { \
if (QK_ISR_CONTEXT_()) { \
lockStat_ = 0xFFU; \
} else { \
lockStat_ = QK::schedLock((ceil_)); \
} \
} while (false)</code>
</operation>
<!--${QK-impl::QF_SCHED_UNLOCK_}-->
<operation name="QF_SCHED_UNLOCK_" type="" visibility="0x03" properties="0x00">
<code>do { \
if (lockStat_ != 0xFFU) { \
QK::schedUnlock(lockStat_); \
} \
} while (false)</code>
</operation>
<!--${QK-impl::QACTIVE_EQUEUE_WAIT_}-->
<operation name="QACTIVE_EQUEUE_WAIT_" type="" visibility="0x03" properties="0x00">
<!--${QK-impl::QACTIVE_EQUEUE_W~::me_}-->
<parameter name="me_" type="QP::QActive *"/>
<code>\
Q_ASSERT_INCRIT(320, (me_)-&gt;m_eQueue.m_frontEvt != nullptr)</code>
</operation>
<!--${QK-impl::QACTIVE_EQUEUE_SIGNAL_}-->
<operation name="QACTIVE_EQUEUE_SIGNAL_?ndef Q_UNSAFE" type="" visibility="0x03" properties="0x00">
<!--${QK-impl::QACTIVE_EQUEUE_S~::me_}-->
<parameter name="me_" type="QP::QActive *"/>
<code>do { \
QK_priv_.readySet.insert( \
static_cast&lt;std::uint_fast8_t&gt;((me_)-&gt;m_prio)); \
QK_priv_.readySet.update_(&amp;QK_priv_.readySet_dis); \
if (!QK_ISR_CONTEXT_()) { \
if (QK_sched_() != 0U) { \
QK_activate_(); \
} \
} \
} while (false)</code>
</operation>
<!--${QK-impl::QACTIVE_EQUEUE_SIGNAL_}-->
<operation name="QACTIVE_EQUEUE_SIGNAL_?def Q_UNSAFE" type="" visibility="0x03" properties="0x00">
<!--${QK-impl::QACTIVE_EQUEUE_S~::me_}-->
<parameter name="me_" type="QP::QActive *"/>
<code>do { \
QK_priv_.readySet.insert( \
static_cast&lt;std::uint_fast8_t&gt;((me_)-&gt;m_prio)); \
if (!QK_ISR_CONTEXT_()) { \
if (QK_sched_() != 0U) { \
QK_activate_(); \
} \
} \
} while (false)</code>
</operation>
</package>
<!--${QXK}-->
<package name="QXK" stereotype="0x05" namespace="QP::">
<!--${QXK::QSchedStatus}-->
<attribute name="QSchedStatus" type="using" visibility="0x04" properties="0x00">
<code>= std::uint_fast16_t;</code>
</attribute>
<!--${QXK::QXTHREAD_NO_TIMEOUT}-->
<attribute name="QXTHREAD_NO_TIMEOUT" type="constexpr QTimeEvtCtr" visibility="0x04" properties="0x01">
<code>{0U};</code>
</attribute>
<!--${QXK::QXK-base}-->
<package name="QXK-base" stereotype="0x02" namespace="QXK::">
<!--${QXK::QXK-base::onIdle}-->
<operation name="onIdle" type="void" visibility="0x00" properties="0x01"/>
<!--${QXK::QXK-base::schedLock}-->
<operation name="schedLock" type="QSchedStatus" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QXK::QXK-base::schedLock::ceiling}-->
<parameter name="ceiling" type="std::uint_fast8_t const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(100, !QXK_ISR_CONTEXT_());
QSchedStatus stat; // saved lock status to be returned
// is the lock ceiling being raised?
if (ceiling &gt; QXK_priv_.lockCeil) {
QS_BEGIN_PRE_(QS_SCHED_LOCK, 0U)
QS_TIME_PRE_(); // timestamp
// the previous lock ceiling &amp; new lock ceiling
QS_2U8_PRE_(static_cast&lt;std::uint8_t&gt;(QXK_priv_.lockCeil),
static_cast&lt;std::uint8_t&gt;(ceiling));
QS_END_PRE_()
// previous status of the lock
stat = static_cast&lt;QSchedStatus&gt;(QXK_priv_.lockHolder);
stat |= static_cast&lt;QSchedStatus&gt;(QXK_priv_.lockCeil) &lt;&lt; 8U;
// new status of the lock
QXK_priv_.lockHolder = (QXK_priv_.curr != nullptr)
? QXK_priv_.curr-&gt;getPrio()
: 0U;
QXK_priv_.lockCeil = ceiling;
}
else {
stat = 0xFFU; // scheduler not locked
}
QF_MEM_APP();
QF_CRIT_EXIT();
return stat; // return the status to be saved in a stack variable</code>
</operation>
<!--${QXK::QXK-base::schedUnlock}-->
<operation name="schedUnlock" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QXK::QXK-base::schedUnlock::stat}-->
<parameter name="stat" type="QSchedStatus const"/>
<code>// has the scheduler been actually locked by the last QXK::schedLock()?
if (stat != 0xFFU) {
std::uint8_t const prevCeil = static_cast&lt;std::uint8_t&gt;(stat &gt;&gt; 8U);
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(200, !QXK_ISR_CONTEXT_());
Q_REQUIRE_INCRIT(201, QXK_priv_.lockCeil &gt; prevCeil);
QS_BEGIN_PRE_(QS_SCHED_UNLOCK, 0U)
QS_TIME_PRE_(); // timestamp
// ceiling before unlocking &amp; prio after unlocking
QS_2U8_PRE_(QXK_priv_.lockCeil, prevCeil);
QS_END_PRE_()
// restore the previous lock ceiling and lock holder
QXK_priv_.lockCeil = prevCeil;
QXK_priv_.lockHolder = (stat &amp; 0xFFU);
// find if any threads should be run after unlocking the scheduler
if (QXK_sched_() != 0U) { // activation needed?
QXK_activate_(); // synchronously activate basic-thred(s)
}
QF_MEM_APP();
QF_CRIT_EXIT();
}</code>
</operation>
<!--${QXK::QXK-base::current}-->
<operation name="current" type="QP::QActive *" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(600, QXK_priv_.lockCeil &lt;= QF_MAX_ACTIVE);
QP::QActive *curr = QXK_priv_.curr;
if (curr == nullptr) { // basic thread?
curr = QP::QActive::registry_[QXK_priv_.actPrio];
}
Q_ASSERT_INCRIT(690, curr != nullptr);
QF_MEM_APP();
QF_CRIT_EXIT();
return curr;</code>
</operation>
</package>
<!--${QXK::QXThread}-->
<class name="QXThread" superclass="QF::QActive">
<!--${QXK::QXThread::m_timeEvt}-->
<attribute name="m_timeEvt" type="QTimeEvt" visibility="0x02" properties="0x00"/>
<!--${QXK::QXThread::QActive}-->
<attribute name="QActive" type="friend class" visibility="0x00" properties="0x00"/>
<!--${QXK::QXThread::QTimeEvt}-->
<attribute name="QTimeEvt" type="friend class" visibility="0x00" properties="0x00"/>
<!--${QXK::QXThread::QXSemaphore}-->
<attribute name="QXSemaphore" type="friend class" visibility="0x00" properties="0x00"/>
<!--${QXK::QXThread::QXMutex}-->
<attribute name="QXMutex" type="friend class" visibility="0x00" properties="0x00"/>
<!--${QXK::QXThread::QXTHREAD_NO_TIMEOUT}-->
<attribute name="QXTHREAD_NO_TIMEOUT" type="static constexpr QTimeEvtCtr" visibility="0x04" properties="0x01">
<code>{0U};</code>
</attribute>
<!--${QXK::QXThread::QXThread}-->
<operation name="QXThread" type="" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QXK::QXThread::QXThread::handler}-->
<parameter name="handler" type="QXThreadHandler const"/>
<!--${QXK::QXThread::QXThread::tickRate = 0U}-->
<parameter name="tickRate = 0U" type="std::uint_fast8_t const"/>
<code> : QActive(Q_STATE_CAST(handler)),
m_timeEvt(this, static_cast&lt;QSignal&gt;(QXK::DELAY_SIG), tickRate)
m_state.act = nullptr; // mark as extended thread</code>
</operation>
<!--${QXK::QXThread::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x00">
<specifiers>override</specifiers>
<!--${QXK::QXThread::init::e}-->
<parameter name="e" type="void const * const"/>
<!--${QXK::QXThread::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>Q_UNUSED_PAR(e);
Q_UNUSED_PAR(qsId);
Q_ERROR_INCRIT(110);</code>
</operation>
<!--${QXK::QXThread::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x06">
<specifiers>override</specifiers>
<!--${QXK::QXThread::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>this-&gt;init(nullptr, qsId);</code>
</operation>
<!--${QXK::QXThread::dispatch}-->
<operation name="dispatch" type="void" visibility="0x00" properties="0x00">
<specifiers>override</specifiers>
<!--${QXK::QXThread::dispatch::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QXK::QXThread::dispatch::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>Q_UNUSED_PAR(e);
Q_UNUSED_PAR(qsId);
Q_ERROR_INCRIT(120);</code>
</operation>
<!--${QXK::QXThread::getTimeEvt}-->
<operation name="getTimeEvt" type="QTimeEvt const *" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return &amp;m_timeEvt;</code>
</operation>
<!--${QXK::QXThread::delay}-->
<operation name="delay" type="bool" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QXK::QXThread::delay::nTicks}-->
<parameter name="nTicks" type="QTimeEvtCtr const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
QXThread * const thr = QXK_PTR_CAST_(QXThread*, QXK_priv_.curr);
// precondition, this function:
// - must NOT be called from an ISR;
// - number of ticks cannot be zero
// - be called from an extended thread;
// - the thread must NOT be already blocked on any object.
Q_REQUIRE_INCRIT(800, (!QXK_ISR_CONTEXT_())
&amp;&amp; (nTicks != 0U)
&amp;&amp; (thr != nullptr)
&amp;&amp; (thr-&gt;m_temp.obj == nullptr));
// - the thread must NOT be holding a scheduler lock.
Q_REQUIRE_INCRIT(801, QXK_priv_.lockHolder != thr-&gt;m_prio);
// remember the blocking object
thr-&gt;m_temp.obj = QXK_PTR_CAST_(QMState const*, &amp;thr-&gt;m_timeEvt);
thr-&gt;teArm_(static_cast&lt;enum_t&gt;(QXK::DELAY_SIG), nTicks);
thr-&gt;block_();
QF_MEM_APP();
QF_CRIT_EXIT();
QF_CRIT_EXIT_NOP(); // BLOCK here
// after unblocking...
QF_CRIT_ENTRY();
QF_MEM_SYS();
// the blocking object must be the time event
Q_ASSERT_INCRIT(890, thr-&gt;m_temp.obj
== QXK_PTR_CAST_(QMState*, &amp;thr-&gt;m_timeEvt));
thr-&gt;m_temp.obj = nullptr; // clear
QF_MEM_APP();
QF_CRIT_EXIT();
// signal of zero means that the time event was posted without
// being canceled.
return (thr-&gt;m_timeEvt.sig == 0U);</code>
</operation>
<!--${QXK::QXThread::delayCancel}-->
<operation name="delayCancel" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
bool wasArmed;
if (m_temp.obj == QXK_PTR_CAST_(QMState*, &amp;m_timeEvt)) {
wasArmed = teDisarm_();
unblock_();
}
else {
wasArmed = false;
}
QF_MEM_APP();
QF_CRIT_EXIT();
return wasArmed;</code>
</operation>
<!--${QXK::QXThread::queueGet}-->
<operation name="queueGet" type="QEvt const *" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QXK::QXThread::queueGet::nTicks = QXTHREAD_NO_TIMEOUT}-->
<parameter name="nTicks = QXTHREAD_NO_TIMEOUT" type="QTimeEvtCtr const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
QXThread * const thr = QXTHREAD_CAST_(QXK_priv_.curr);
// precondition, this function:
// - must NOT be called from an ISR;
// - be called from an extended thread;
// - the thread must NOT be already blocked on any object.
Q_REQUIRE_INCRIT(500, (!QXK_ISR_CONTEXT_())
&amp;&amp; (thr != nullptr)
&amp;&amp; (thr-&gt;m_temp.obj == nullptr));
// - the thread must NOT be holding a scheduler lock.
Q_REQUIRE_INCRIT(501, QXK_priv_.lockHolder != thr-&gt;m_prio);
// is the queue empty?
if (thr-&gt;m_eQueue.m_frontEvt == nullptr) {
// remember the blocking object (the thread's queue)
thr-&gt;m_temp.obj = QXK_PTR_CAST_(QMState*, &amp;thr-&gt;m_eQueue);
thr-&gt;teArm_(static_cast&lt;enum_t&gt;(QXK::TIMEOUT_SIG), nTicks);
QXK_priv_.readySet.remove(
static_cast&lt;std::uint_fast8_t&gt;(thr-&gt;m_prio));
#ifndef Q_UNSAFE
QXK_priv_.readySet.update_(&amp;QXK_priv_.readySet_dis);
#endif
static_cast&lt;void&gt;(QXK_sched_()); // synchronous scheduling
QF_MEM_APP();
QF_CRIT_EXIT();
QF_CRIT_EXIT_NOP(); // BLOCK here
// after unblocking...
QF_CRIT_ENTRY();
QF_MEM_SYS();
// the blocking object must be this queue
Q_ASSERT_INCRIT(510, thr-&gt;m_temp.obj ==
QXK_PTR_CAST_(QMState *, &amp;thr-&gt;m_eQueue));
thr-&gt;m_temp.obj = nullptr; // clear
}
// is the queue not empty?
QEvt const *e;
if (thr-&gt;m_eQueue.m_frontEvt != nullptr) {
e = thr-&gt;m_eQueue.m_frontEvt; // remove from the front
QEQueueCtr const nFree = thr-&gt;m_eQueue.m_nFree + 1U;
thr-&gt;m_eQueue.m_nFree = nFree; // update the # free
// any events in the ring buffer?
if (nFree &lt;= thr-&gt;m_eQueue.m_end) {
// remove event from the tail
thr-&gt;m_eQueue.m_frontEvt =
thr-&gt;m_eQueue.m_ring[thr-&gt;m_eQueue.m_tail];
if (thr-&gt;m_eQueue.m_tail == 0U) {
thr-&gt;m_eQueue.m_tail = thr-&gt;m_eQueue.m_end; // wrap
}
// advance the tail (counter clockwise)
thr-&gt;m_eQueue.m_tail = (thr-&gt;m_eQueue.m_tail - 1U);
QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, thr-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(e-&gt;sig); // the signal of this event
QS_OBJ_PRE_(&amp;thr); // this active object
QS_2U8_PRE_(e-&gt;getPoolNum_(), e-&gt;refCtr_); // poolNum &amp; refCtr
QS_EQC_PRE_(nFree); // # free entries
QS_END_PRE_()
}
else {
thr-&gt;m_eQueue.m_frontEvt = nullptr; // empty queue
// all entries in the queue must be free (+1 for fronEvt)
Q_ASSERT_INCRIT(520, nFree == (thr-&gt;m_eQueue.m_end + 1U));
QS_BEGIN_PRE_(QS_QF_ACTIVE_GET_LAST, thr-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(e-&gt;sig); // the signal of this event
QS_OBJ_PRE_(&amp;thr); // this active object
QS_2U8_PRE_(e-&gt;getPoolNum_(), e-&gt;refCtr_); // poolNum &amp; refCtr
QS_END_PRE_()
}
}
else { // the queue is still empty -- the timeout must have fired
e = nullptr;
}
QF_MEM_APP();
QF_CRIT_EXIT();
return e;</code>
</operation>
<!--${QXK::QXThread::block_}-->
<operation name="block_" type="void" visibility="0x02" properties="0x00">
<specifiers>const noexcept</specifiers>
<code>// NOTE: must be called IN a critical section
Q_REQUIRE_INCRIT(600, (QXK_priv_.lockHolder != m_prio));
QXK_priv_.readySet.remove(static_cast&lt;std::uint_fast8_t&gt;(m_prio));
#ifndef Q_UNSAFE
QXK_priv_.readySet.update_(&amp;QXK_priv_.readySet_dis);
#endif
static_cast&lt;void&gt;(QXK_sched_()); // schedule other threads</code>
</operation>
<!--${QXK::QXThread::unblock_}-->
<operation name="unblock_" type="void" visibility="0x02" properties="0x00">
<specifiers>const noexcept</specifiers>
<code>// NOTE: must be called IN a critical section
QXK_priv_.readySet.insert(static_cast&lt;std::uint_fast8_t&gt;(m_prio));
#ifndef Q_UNSAFE
QXK_priv_.readySet.update_(&amp;QXK_priv_.readySet_dis);
#endif
if ((!QXK_ISR_CONTEXT_()) // not inside ISR?
&amp;&amp; (QActive::registry_[0] != nullptr)) // kernel started?
{
static_cast&lt;void&gt;(QXK_sched_()); // schedule other threads
}</code>
</operation>
<!--${QXK::QXThread::timeout_}-->
<operation name="timeout_" type="void" visibility="0x02" properties="0x01">
<!--${QXK::QXThread::timeout_::act}-->
<parameter name="act" type="QActive * const"/>
<code>// NOTE: must be called IN a critical section
// the private time event is now disarmed and not in any queue,
// so it is safe to change its signal. The signal of 0 means
// that the time event has expired.
QXTHREAD_CAST_(act)-&gt;m_timeEvt.sig = 0U;
QXTHREAD_CAST_(act)-&gt;unblock_();</code>
</operation>
<!--${QXK::QXThread::teArm_}-->
<operation name="teArm_" type="void" visibility="0x02" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QXK::QXThread::teArm_::sig}-->
<parameter name="sig" type="enum_t const"/>
<!--${QXK::QXThread::teArm_::nTicks}-->
<parameter name="nTicks" type="QTimeEvtCtr const"/>
<code>// NOTE: must be called IN a critical section
// precondition:
// - the time event must be unused
Q_REQUIRE_INCRIT(700, m_timeEvt.m_ctr == 0U);
m_timeEvt.sig = static_cast&lt;QSignal&gt;(sig);
if (nTicks != QXTHREAD_NO_TIMEOUT) {
m_timeEvt.m_ctr = static_cast&lt;QTimeEvtCtr&gt;(nTicks);
m_timeEvt.m_interval = 0U;
// is the time event unlinked?
// NOTE: For the duration of a single clock tick of the specified tick
// rate a time event can be disarmed and yet still linked in the list,
// because un-linking is performed exclusively in QTimeEvt::tickX().
if (static_cast&lt;std::uint8_t&gt;(m_timeEvt.refCtr_ &amp; TE_IS_LINKED) == 0U)
{
std::uint_fast8_t const tickRate =
static_cast&lt;std::uint_fast8_t&gt;(m_timeEvt.refCtr_);
Q_ASSERT_INCRIT(710, tickRate &lt; QF_MAX_TICK_RATE);
// mark as linked
m_timeEvt.refCtr_ = static_cast&lt;std::uint8_t&gt;(
m_timeEvt.refCtr_ | TE_IS_LINKED);
// The time event is initially inserted into the separate
// &quot;freshly armed&quot; list based on timeEvtHead_[tickRate].act.
// Only later, inside QTimeEvt::tick(), the &quot;freshly armed&quot;
// list is appended to the main list of armed time events based on
// timeEvtHead_[tickRate].next. Again, this is to keep any
// changes to the main list exclusively inside QTimeEvt::tick().
m_timeEvt.m_next
= QXK_PTR_CAST_(QTimeEvt*,
QTimeEvt::timeEvtHead_[tickRate].m_act);
QTimeEvt::timeEvtHead_[tickRate].m_act = &amp;m_timeEvt;
}
}</code>
</operation>
<!--${QXK::QXThread::teDisarm_}-->
<operation name="teDisarm_" type="bool" visibility="0x02" properties="0x00">
<specifiers>noexcept</specifiers>
<code>// NOTE: must be called IN a critical section
bool wasArmed;
// is the time evt running?
if (m_timeEvt.m_ctr != 0U) {
wasArmed = true;
// schedule removal from list
m_timeEvt.m_ctr = 0U;
}
// the time event was already automatically disarmed
else {
wasArmed = false;
}
return wasArmed;</code>
</operation>
<!--${QXK::QXThread::stackInit_}-->
<operation name="stackInit_" type="void" visibility="0x02" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QXK::QXThread::stackInit_::handler}-->
<parameter name="handler" type=" QP::QXThreadHandler const"/>
<!--${QXK::QXThread::stackInit_::stkSto}-->
<parameter name="stkSto" type="void * const"/>
<!--${QXK::QXThread::stackInit_::stkSize}-->
<parameter name="stkSize" type="std::uint_fast16_t const"/>
</operation>
</class>
<!--${QXK::QXSemaphore}-->
<class name="QXSemaphore">
<!--${QXK::QXSemaphore::m_waitSet}-->
<attribute name="m_waitSet" type="QPSet" visibility="0x02" properties="0x00"/>
<!--${QXK::QXSemaphore::m_count}-->
<attribute name="m_count" type="std::uint8_t" visibility="0x02" properties="0x00"/>
<!--${QXK::QXSemaphore::m_max_count}-->
<attribute name="m_max_count" type="std::uint8_t" visibility="0x02" properties="0x00"/>
<!--${QXK::QXSemaphore::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QXK::QXSemaphore::init::count}-->
<parameter name="count" type="std::uint_fast8_t const"/>
<!--${QXK::QXSemaphore::init::max_count = 0xFFU}-->
<parameter name="max_count = 0xFFU" type="std::uint_fast8_t const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(100, (count &lt;= max_count)
&amp;&amp; (0U &lt; max_count) &amp;&amp; (max_count &lt;= 0xFFU));
m_count = static_cast&lt;std::uint8_t&gt;(count);
m_max_count = static_cast&lt;std::uint8_t&gt;(max_count);
m_waitSet.setEmpty();
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QXK::QXSemaphore::wait}-->
<operation name="wait" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QXK::QXSemaphore::wait::nTicks = QXTHREAD_NO_TIMEOUT}-->
<parameter name="nTicks = QXTHREAD_NO_TIMEOUT" type="QTimeEvtCtr const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
QXThread * const curr = QXK_PTR_CAST_(QXThread*, QXK_priv_.curr);
// precondition, this function:
// - must NOT be called from an ISR;
// - the semaphore must be initialized
// - be called from an extended thread;
// - the thread must NOT be already blocked on any object.
Q_REQUIRE_INCRIT(200, (!QXK_ISR_CONTEXT_())
&amp;&amp; (m_max_count &gt; 0U)
&amp;&amp; (curr != nullptr)
&amp;&amp; (curr-&gt;m_temp.obj == nullptr));
// - the thread must NOT be holding a scheduler lock.
Q_REQUIRE_INCRIT(201, QXK_priv_.lockHolder != curr-&gt;m_prio);
bool taken = true; // assume that the semaphore will be signaled
if (m_count &gt; 0U) {
m_count = m_count - 1U; // semaphore taken: decrement the count
QS_BEGIN_PRE_(QS_SEM_TAKE, curr-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this semaphore
QS_2U8_PRE_(curr-&gt;m_prio, m_count);
QS_END_PRE_()
}
else { // semaphore not available -- BLOCK the thread
std::uint_fast8_t const p =
static_cast&lt;std::uint_fast8_t&gt;(curr-&gt;m_prio);
// remove the curr prio from the ready set (will block)
// and insert to the waiting set on this semaphore
QXK_priv_.readySet.remove(p);
#ifndef Q_UNSAFE
QXK_priv_.readySet.update_(&amp;QXK_priv_.readySet_dis);
#endif
m_waitSet.insert(p);
// remember the blocking object (this semaphore)
curr-&gt;m_temp.obj = QXK_PTR_CAST_(QMState*, this);
curr-&gt;teArm_(static_cast&lt;enum_t&gt;(QXK::TIMEOUT_SIG), nTicks);
QS_BEGIN_PRE_(QS_SEM_BLOCK, curr-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this semaphore
QS_2U8_PRE_(curr-&gt;m_prio, m_count);
QS_END_PRE_()
// schedule the next thread if multitasking started
static_cast&lt;void&gt;(QXK_sched_()); // schedule other threads
QF_MEM_APP();
QF_CRIT_EXIT();
QF_CRIT_EXIT_NOP(); // BLOCK here !!!
QF_CRIT_ENTRY(); // AFTER unblocking...
QF_MEM_SYS();
// the blocking object must be this semaphore
Q_ASSERT_INCRIT(240, curr-&gt;m_temp.obj
== QXK_PTR_CAST_(QMState*, this));
// did the blocking time-out? (signal of zero means that it did)
if (curr-&gt;m_timeEvt.sig == 0U) {
if (m_waitSet.hasElement(p)) { // still waiting?
m_waitSet.remove(p); // remove unblocked thread
taken = false; // the semaphore was NOT taken
}
}
else { // blocking did NOT time out
// the thread must NOT be waiting on this semaphore
Q_ASSERT_INCRIT(250, !m_waitSet.hasElement(p));
}
curr-&gt;m_temp.obj = nullptr; // clear blocking obj.
}
QF_MEM_APP();
QF_CRIT_EXIT();
return taken;</code>
</operation>
<!--${QXK::QXSemaphore::tryWait}-->
<operation name="tryWait" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
// precondition:
// - the semaphore must be initialized
Q_REQUIRE_INCRIT(300, m_max_count &gt; 0U);
#ifdef Q_SPY
QActive const * const curr = QXK_PTR_CAST_(QActive*, QXK_priv_.curr);
#endif // Q_SPY
bool taken;
// is the semaphore available?
if (m_count &gt; 0U) {
m_count = m_count - 1U; // semaphore signaled: decrement
taken = true;
QS_BEGIN_PRE_(QS_SEM_TAKE, curr-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this semaphore
QS_2U8_PRE_(curr-&gt;m_prio, m_count);
QS_END_PRE_()
}
else { // the semaphore is NOT available (would block)
taken = false;
QS_BEGIN_PRE_(QS_SEM_BLOCK_ATTEMPT, curr-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this semaphore
QS_2U8_PRE_(curr-&gt;m_prio, m_count);
QS_END_PRE_()
}
QF_MEM_APP();
QF_CRIT_EXIT();
return taken;</code>
</operation>
<!--${QXK::QXSemaphore::signal}-->
<operation name="signal" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>bool signaled = true; // assume that the semaphore will be signaled
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
// precondition:
// - the semaphore must be initialized
Q_REQUIRE_INCRIT(400, m_max_count &gt; 0U);
// any threads blocked on this semaphore?
if (m_waitSet.notEmpty()) {
// find the highest-prio. thread waiting on this semaphore
std::uint_fast8_t const p = m_waitSet.findMax();
QXThread * const thr =
QXK_PTR_CAST_(QXThread*, QActive::registry_[p]);
// assert that the thread:
// - must be registered in QF;
// - must be extended; and
// - must be blocked on this semaphore;
Q_ASSERT_INCRIT(410, (thr != nullptr)
&amp;&amp; (thr-&gt;m_osObject != nullptr)
&amp;&amp; (thr-&gt;m_temp.obj
== QXK_PTR_CAST_(QMState*, this)));
// disarm the internal time event
static_cast&lt;void&gt;(thr-&gt;teDisarm_());
// make the thread ready to run and remove from the wait-list
QXK_priv_.readySet.insert(p);
#ifndef Q_UNSAFE
QXK_priv_.readySet.update_(&amp;QXK_priv_.readySet_dis);
#endif
m_waitSet.remove(p);
QS_BEGIN_PRE_(QS_SEM_TAKE, thr-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this semaphore
QS_2U8_PRE_(thr-&gt;m_prio, m_count);
QS_END_PRE_()
if (!QXK_ISR_CONTEXT_()) { // not inside ISR?
static_cast&lt;void&gt;(QXK_sched_()); // schedule other threads
}
}
else if (m_count &lt; m_max_count) {
m_count = m_count + 1U; // semaphore signaled: increment
QS_BEGIN_PRE_(QS_SEM_SIGNAL, 0U)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this semaphore
QS_2U8_PRE_(0U, m_count);
QS_END_PRE_()
}
else {
signaled = false; // semaphore NOT signaled
}
QF_MEM_APP();
QF_CRIT_EXIT();
return signaled;</code>
</operation>
</class>
<!--${QXK::QXMutex}-->
<class name="QXMutex">
<!--${QXK::QXMutex::m_ao}-->
<attribute name="m_ao" type="QActive" visibility="0x02" properties="0x00"/>
<!--${QXK::QXMutex::m_waitSet}-->
<attribute name="m_waitSet" type="QPSet" visibility="0x02" properties="0x00"/>
<!--${QXK::QXMutex::QXMutex}-->
<operation name="QXMutex" type="" visibility="0x00" properties="0x00">
<code> : m_ao(Q_STATE_CAST(0))</code>
</operation>
<!--${QXK::QXMutex::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QXK::QXMutex::init::prioSpec}-->
<parameter name="prioSpec" type="QPrioSpec const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(100, (prioSpec &amp; 0xFF00U) == 0U);
m_ao.m_prio = static_cast&lt;std::uint8_t&gt;(prioSpec &amp; 0xFFU); // QF-prio.
m_ao.m_pthre = 0U; // not used
QActive &amp;ao = m_ao;
QF_MEM_APP();
QF_CRIT_EXIT();
ao.register_(); // register this mutex as AO</code>
</operation>
<!--${QXK::QXMutex::lock}-->
<operation name="lock" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QXK::QXMutex::lock::nTicks = QXTHREAD_NO_TIMEOUT}-->
<parameter name="nTicks = QXTHREAD_NO_TIMEOUT" type="QTimeEvtCtr const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
QXThread * const curr = QXK_PTR_CAST_(QXThread*, QXK_priv_.curr);
// precondition, this mutex operation must:
// - NOT be called from an ISR;
// - be called from an eXtended thread;
// - the mutex-prio. must be in range;
// - the thread must NOT be already blocked on any object.
Q_REQUIRE_INCRIT(200, (!QXK_ISR_CONTEXT_())
&amp;&amp; (curr != nullptr)
&amp;&amp; (m_ao.m_prio &lt;= QF_MAX_ACTIVE)
&amp;&amp; (curr-&gt;m_temp.obj == nullptr));
// also: the thread must NOT be holding a scheduler lock.
Q_REQUIRE_INCRIT(201, QXK_priv_.lockHolder != curr-&gt;m_prio);
// is the mutex available?
bool locked = true; // assume that the mutex will be locked
if (m_ao.m_eQueue.m_nFree == 0U) {
m_ao.m_eQueue.m_nFree = 1U; // mutex lock nesting
// also: the newly locked mutex must have no holder yet
Q_REQUIRE_INCRIT(203, m_ao.m_osObject == nullptr);
// set the new mutex holder to the curr thread and
// save the thread's prio in the mutex
// NOTE: reuse the otherwise unused eQueue data member.
m_ao.m_osObject = curr;
m_ao.m_eQueue.m_head = static_cast&lt;QEQueueCtr&gt;(curr-&gt;m_prio);
QS_BEGIN_PRE_(QS_MTX_LOCK, curr-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this mutex
QS_U8_PRE_(static_cast&lt;std::uint8_t&gt;(m_ao.m_eQueue.m_head));
QS_U8_PRE_(static_cast&lt;std::uint8_t&gt;(m_ao.m_eQueue.m_nFree));
QS_END_PRE_()
if (m_ao.m_prio != 0U) { // prio.-ceiling protocol used?
// the holder prio. must be lower than that of the mutex
// and the prio. slot must be occupied by this mutex
Q_ASSERT_INCRIT(210, (curr-&gt;m_prio &lt; m_ao.m_prio)
&amp;&amp; (QActive::registry_[m_ao.m_prio] == &amp;m_ao));
// remove the thread's original prio from the ready set
// and insert the mutex's prio into the ready set
QXK_priv_.readySet.remove(
static_cast&lt;std::uint_fast8_t&gt;(m_ao.m_eQueue.m_head));
QXK_priv_.readySet.insert(
static_cast&lt;std::uint_fast8_t&gt;(m_ao.m_prio));
#ifndef Q_UNSAFE
QXK_priv_.readySet.update_(&amp;QXK_priv_.readySet_dis);
#endif
// put the thread into the AO registry in place of the mutex
QActive::registry_[m_ao.m_prio] = curr;
// set thread's prio to that of the mutex
curr-&gt;m_prio = m_ao.m_prio;
#ifndef Q_UNSAFE
curr-&gt;m_prio_dis = static_cast&lt;std::uint8_t&gt;(~curr-&gt;m_prio);
#endif
}
}
// is the mutex locked by this thread already (nested locking)?
else if (m_ao.m_osObject == curr) {
// the nesting level beyond the arbitrary but high bound
// most likely means cyclic or recursive locking of a mutex.
Q_ASSERT_INCRIT(220, m_ao.m_eQueue.m_nFree &lt; 0xFFU);
// lock one more level
m_ao.m_eQueue.m_nFree = m_ao.m_eQueue.m_nFree + 1U;
QS_BEGIN_PRE_(QS_MTX_LOCK, curr-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this mutex
QS_U8_PRE_(static_cast&lt;std::uint8_t&gt;(m_ao.m_eQueue.m_head));
QS_U8_PRE_(static_cast&lt;std::uint8_t&gt;(m_ao.m_eQueue.m_nFree));
QS_END_PRE_()
}
else { // the mutex is already locked by a different thread
// the mutex holder must be valid
Q_ASSERT_INCRIT(230, m_ao.m_osObject != nullptr);
if (m_ao.m_prio != 0U) { // prio.-ceiling protocol used?
// the prio slot must be occupied by the thr. holding the mutex
Q_ASSERT_INCRIT(240, QActive::registry_[m_ao.m_prio]
== QXK_PTR_CAST_(QActive const *, m_ao.m_osObject));
}
// remove the curr thread's prio from the ready set (will block)
// and insert it to the waiting set on this mutex
std::uint_fast8_t const p =
static_cast&lt;std::uint_fast8_t&gt;(curr-&gt;m_prio);
QXK_priv_.readySet.remove(p);
#ifndef Q_UNSAFE
QXK_priv_.readySet.update_(&amp;QXK_priv_.readySet_dis);
#endif
m_waitSet.insert(p);
// set the blocking object (this mutex)
curr-&gt;m_temp.obj = QXK_PTR_CAST_(QMState*, this);
curr-&gt;teArm_(static_cast&lt;enum_t&gt;(QXK::TIMEOUT_SIG), nTicks);
QS_BEGIN_PRE_(QS_MTX_BLOCK, curr-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this mutex
QS_2U8_PRE_(static_cast&lt;std::uint8_t&gt;(m_ao.m_eQueue.m_head),
curr-&gt;m_prio);
QS_END_PRE_()
// schedule the next thread if multitasking started
static_cast&lt;void&gt;(QXK_sched_()); // schedule other threads
QF_MEM_APP();
QF_CRIT_EXIT();
QF_CRIT_EXIT_NOP(); // BLOCK here !!!
// AFTER unblocking...
QF_CRIT_ENTRY();
QF_MEM_SYS();
// the blocking object must be this mutex
Q_ASSERT_INCRIT(250, curr-&gt;m_temp.obj
== QXK_PTR_CAST_(QMState*, this));
// did the blocking time-out? (signal of zero means that it did)
if (curr-&gt;m_timeEvt.sig == 0U) {
if (m_waitSet.hasElement(p)) { // still waiting?
m_waitSet.remove(p); // remove unblocked thread
locked = false; // the mutex was NOT locked
}
}
else { // blocking did NOT time out
// the thread must NOT be waiting on this mutex
Q_ASSERT_INCRIT(260, !m_waitSet.hasElement(p));
}
curr-&gt;m_temp.obj = nullptr; // clear blocking obj.
}
QF_MEM_APP();
QF_CRIT_EXIT();
return locked;</code>
</operation>
<!--${QXK::QXMutex::tryLock}-->
<operation name="tryLock" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
QActive *curr = QXK_priv_.curr;
if (curr == nullptr) { // called from a basic thread?
curr = QActive::registry_[QXK_priv_.actPrio];
}
// precondition, this mutex must:
// - NOT be called from an ISR;
// - the calling thread must be valid;
// - the mutex-prio. must be in range
Q_REQUIRE_INCRIT(300, (!QXK_ISR_CONTEXT_())
&amp;&amp; (curr != nullptr)
&amp;&amp; (m_ao.m_prio &lt;= QF_MAX_ACTIVE));
// also: the thread must NOT be holding a scheduler lock.
Q_REQUIRE_INCRIT(301,
QXK_priv_.lockHolder != static_cast&lt;std::uint_fast8_t&gt;(curr-&gt;m_prio));
// is the mutex available?
if (m_ao.m_eQueue.m_nFree == 0U) {
m_ao.m_eQueue.m_nFree = 1U; // mutex lock nesting
// also the newly locked mutex must have no holder yet
Q_REQUIRE_INCRIT(303, m_ao.m_osObject == nullptr);
// set the new mutex holder to the curr thread and
// save the thread's prio in the mutex
// NOTE: reuse the otherwise unused eQueue data member.
m_ao.m_osObject = curr;
m_ao.m_eQueue.m_head = static_cast&lt;QEQueueCtr&gt;(curr-&gt;m_prio);
QS_BEGIN_PRE_(QS_MTX_LOCK, curr-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this mutex
QS_U8_PRE_(static_cast&lt;std::uint8_t&gt;(m_ao.m_eQueue.m_head));
QS_U8_PRE_(static_cast&lt;std::uint8_t&gt;(m_ao.m_eQueue.m_nFree));
QS_END_PRE_()
if (m_ao.m_prio != 0U) { // prio.-ceiling protocol used?
// the holder prio. must be lower than that of the mutex
// and the prio. slot must be occupied by this mutex
Q_ASSERT_INCRIT(310, (curr-&gt;m_prio &lt; m_ao.m_prio)
&amp;&amp; (QActive::registry_[m_ao.m_prio] == &amp;m_ao));
// remove the thread's original prio from the ready set
// and insert the mutex's prio into the ready set
QXK_priv_.readySet.remove(
static_cast&lt;std::uint_fast8_t&gt;(m_ao.m_eQueue.m_head));
QXK_priv_.readySet.insert(
static_cast&lt;std::uint_fast8_t&gt;(m_ao.m_prio));
#ifndef Q_UNSAFE
QXK_priv_.readySet.update_(&amp;QXK_priv_.readySet_dis);
#endif
// put the thread into the AO registry in place of the mutex
QActive::registry_[m_ao.m_prio] = curr;
// set thread's prio to that of the mutex
curr-&gt;m_prio = m_ao.m_prio;
#ifndef Q_UNSAFE
curr-&gt;m_prio_dis = static_cast&lt;std::uint8_t&gt;(~curr-&gt;m_prio);
#endif
}
}
// is the mutex locked by this thread already (nested locking)?
else if (m_ao.m_osObject == curr) {
// the nesting level must not exceed the specified bound
Q_ASSERT_INCRIT(320, m_ao.m_eQueue.m_nFree &lt; 0xFFU);
// lock one more level
m_ao.m_eQueue.m_nFree = m_ao.m_eQueue.m_nFree + 1U;
QS_BEGIN_PRE_(QS_MTX_LOCK, curr-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this mutex
QS_U8_PRE_(static_cast&lt;std::uint8_t&gt;(m_ao.m_eQueue.m_head));
QS_U8_PRE_(static_cast&lt;std::uint8_t&gt;(m_ao.m_eQueue.m_nFree));
QS_END_PRE_()
}
else { // the mutex is already locked by a different thread
if (m_ao.m_prio != 0U) { // prio.-ceiling protocol used?
// the prio slot must be occupied by the thr. holding the mutex
Q_ASSERT_INCRIT(330, QActive::registry_[m_ao.m_prio]
== QXK_PTR_CAST_(QActive const *, m_ao.m_osObject));
}
QS_BEGIN_PRE_(QS_MTX_BLOCK_ATTEMPT, curr-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this mutex
QS_2U8_PRE_(static_cast&lt;std::uint8_t&gt;(m_ao.m_eQueue.m_head),
curr-&gt;m_prio); // trying thread prio
QS_END_PRE_()
curr = nullptr; // means that mutex is NOT available
}
QF_MEM_APP();
QF_CRIT_EXIT();
return curr != nullptr;</code>
</operation>
<!--${QXK::QXMutex::unlock}-->
<operation name="unlock" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
QActive *curr = QXK_priv_.curr;
if (curr == nullptr) { // called from a basic thread?
curr = QActive::registry_[QXK_priv_.actPrio];
}
Q_REQUIRE_INCRIT(400, (!QXK_ISR_CONTEXT_())
&amp;&amp; (curr != nullptr));
Q_REQUIRE_INCRIT(401, m_ao.m_eQueue.m_nFree &gt; 0U);
Q_REQUIRE_INCRIT(403, m_ao.m_osObject == curr);
// is this the last nesting level?
if (m_ao.m_eQueue.m_nFree == 1U) {
if (m_ao.m_prio != 0U) { // prio.-ceiling protocol used?
Q_ASSERT_INCRIT(410, m_ao.m_prio &lt; QF_MAX_ACTIVE);
// restore the holding thread's prio from the mutex
curr-&gt;m_prio =
static_cast&lt;std::uint8_t&gt;(m_ao.m_eQueue.m_head);
#ifndef Q_UNSAFE
curr-&gt;m_prio_dis = static_cast&lt;std::uint8_t&gt;(~curr-&gt;m_prio);
#endif
// put the mutex back into the AO registry
QActive::registry_[m_ao.m_prio] = &amp;m_ao;
// remove the mutex' prio from the ready set
// and insert the original thread's prio.
QXK_priv_.readySet.remove(
static_cast&lt;std::uint_fast8_t&gt;(m_ao.m_prio));
QXK_priv_.readySet.insert(
static_cast&lt;std::uint_fast8_t&gt;(m_ao.m_eQueue.m_head));
#ifndef Q_UNSAFE
QXK_priv_.readySet.update_(&amp;QXK_priv_.readySet_dis);
#endif
}
QS_BEGIN_PRE_(QS_MTX_UNLOCK, curr-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this mutex
QS_2U8_PRE_(static_cast&lt;std::uint8_t&gt;(m_ao.m_eQueue.m_head),
0U);
QS_END_PRE_()
// are any other threads waiting on this mutex?
if (m_waitSet.notEmpty()) {
// find the highest-prio. thread waiting on this mutex
std::uint_fast8_t const p = m_waitSet.findMax();
// remove this thread from waiting on the mutex
// and insert it into the ready set.
m_waitSet.remove(p);
QXK_priv_.readySet.insert(p);
#ifndef Q_UNSAFE
QXK_priv_.readySet.update_(&amp;QXK_priv_.readySet_dis);
#endif
QXThread * const thr =
QXK_PTR_CAST_(QXThread*, QActive::registry_[p]);
// the waiting thread must:
// - be registered in QF
// - have the prio. corresponding to the registration
// - be an extended thread
// - be blocked on this mutex
Q_ASSERT_INCRIT(420, (thr != nullptr)
&amp;&amp; (thr-&gt;m_prio == static_cast&lt;std::uint8_t&gt;(p))
&amp;&amp; (thr-&gt;m_state.act == Q_ACTION_CAST(0))
&amp;&amp; (thr-&gt;m_temp.obj == QXK_PTR_CAST_(QMState*, this)));
// disarm the internal time event
static_cast&lt;void&gt;(thr-&gt;teDisarm_());
// set the new mutex holder to the curr thread and
// save the thread's prio in the mutex
// NOTE: reuse the otherwise unused eQueue data member.
m_ao.m_osObject = thr;
m_ao.m_eQueue.m_head = static_cast&lt;QEQueueCtr&gt;(thr-&gt;m_prio);
QS_BEGIN_PRE_(QS_MTX_LOCK, thr-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this mutex
QS_U8_PRE_(static_cast&lt;std::uint8_t&gt;(m_ao.m_eQueue.m_head));
QS_U8_PRE_(static_cast&lt;std::uint8_t&gt;(m_ao.m_eQueue.m_nFree));
QS_END_PRE_()
if (m_ao.m_prio != 0U) { // prio.-ceiling protocol used?
// the holder prio. must be lower than that of the mutex
Q_ASSERT_INCRIT(430, (m_ao.m_prio &lt; QF_MAX_ACTIVE)
&amp;&amp; (thr-&gt;m_prio &lt; m_ao.m_prio));
// put the thread into AO registry in place of the mutex
QActive::registry_[m_ao.m_prio] = thr;
}
}
else { // no threads are waiting for this mutex
m_ao.m_eQueue.m_nFree = 0U; // free up the nesting count
// the mutex no longer held by any thread
m_ao.m_osObject = nullptr;
m_ao.m_eQueue.m_head = 0U;
m_ao.m_eQueue.m_tail = 0U;
if (m_ao.m_prio != 0U) { // prio.-ceiling protocol used?
// the AO priority must be in range
Q_ASSERT_INCRIT(440, m_ao.m_prio &lt; QF_MAX_ACTIVE);
// put the mutex back at the original mutex slot
QActive::registry_[m_ao.m_prio] = &amp;m_ao;
}
}
// schedule the next thread if multitasking started
if (QXK_sched_() != 0U) { // activation needed?
QXK_activate_(); // synchronously activate basic-thred(s)
}
}
else { // releasing one level of nested mutex lock
// unlock one level
m_ao.m_eQueue.m_nFree = m_ao.m_eQueue.m_nFree - 1U;
QS_BEGIN_PRE_(QS_MTX_UNLOCK_ATTEMPT, curr-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(this); // this mutex
QS_U8_PRE_(static_cast&lt;std::uint8_t&gt;(m_ao.m_eQueue.m_head));
QS_U8_PRE_(static_cast&lt;std::uint8_t&gt;(m_ao.m_eQueue.m_nFree));
QS_END_PRE_()
}
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
</class>
<!--${QXK::QF-cust}-->
<package name="QF-cust" stereotype="0x02" namespace="QF::">
<!--${QXK::QF-cust::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x01">
<code>bzero_(&amp;QF::priv_, sizeof(QF::priv_));
bzero_(&amp;QXK_priv_, sizeof(QXK_priv_));
bzero_(&amp;QActive::registry_[0], sizeof(QActive::registry_));
#ifndef Q_UNSAFE
QXK_priv_.readySet.update_(&amp;QXK_priv_.readySet_dis);
#endif
// setup the QXK scheduler as initially locked and not running
QXK_priv_.lockCeil = (QF_MAX_ACTIVE + 1U); // scheduler locked
// storage capable for holding a blank QActive object (const in ROM)
static void* const
idle_ao[((sizeof(QActive) + sizeof(void*)) - 1U) / sizeof(void*)]
= { nullptr };
// register the idle AO object (cast 'const' away)
QActive::registry_[0] = QF_CONST_CAST_(QActive*,
reinterpret_cast&lt;QActive const*&gt;(idle_ao));
#ifdef QXK_INIT
QXK_INIT(); // port-specific initialization of the QXK kernel
#endif</code>
</operation>
<!--${QXK::QF-cust::stop}-->
<operation name="stop" type="void" visibility="0x00" properties="0x01">
<code>onCleanup(); // cleanup callback
// nothing else to do for the QXK preemptive kernel</code>
</operation>
<!--${QXK::QF-cust::run}-->
<operation name="run" type="int_t" visibility="0x00" properties="0x01">
<code>#ifdef Q_SPY
QS_SIG_DICTIONARY(QXK::DELAY_SIG, nullptr);
QS_SIG_DICTIONARY(QXK::TIMEOUT_SIG, nullptr);
// produce the QS_QF_RUN trace record
QF_INT_DISABLE();
QF_MEM_SYS();
QS::beginRec_(QS_REC_NUM_(QS_QF_RUN));
QS::endRec_();
QF_MEM_APP();
QF_INT_ENABLE();
#endif // Q_SPY
onStartup(); // application-specific startup callback
QF_INT_DISABLE();
QF_MEM_SYS();
#ifdef QXK_START
QXK_START(); // port-specific startup of the QXK kernel
#endif
QXK_priv_.lockCeil = 0U; // unlock the QXK scheduler
// activate AOs to process events posted so far
if (QXK_sched_() != 0U) {
QXK_activate_();
}
QF_MEM_APP();
QF_INT_ENABLE();
for (;;) { // QXK idle loop...
QXK::onIdle(); // application-specific QXK idle callback
}
#ifdef __GNUC__ // GNU compiler?
return 0;
#endif</code>
</operation>
</package>
<!--${QXK::QActive}-->
<class name="QActive" superclass="qpcpp::QAsm">
<!--${QXK::QActive::start}-->
<operation name="start" type="void" visibility="0x00" properties="0x00">
<!--${QXK::QActive::start::prioSpec}-->
<parameter name="prioSpec" type="QPrioSpec const"/>
<!--${QXK::QActive::start::qSto}-->
<parameter name="qSto" type="QEvt const * * const"/>
<!--${QXK::QActive::start::qLen}-->
<parameter name="qLen" type="std::uint_fast16_t const"/>
<!--${QXK::QActive::start::stkSto}-->
<parameter name="stkSto" type="void * const"/>
<!--${QXK::QActive::start::stkSize}-->
<parameter name="stkSize" type="std::uint_fast16_t const"/>
<!--${QXK::QActive::start::par}-->
<parameter name="par" type="void const * const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(300, (!QXK_ISR_CONTEXT_())
&amp;&amp; ((prioSpec &amp; 0xFF00U) == 0U));
QF_CRIT_EXIT();
m_prio = static_cast&lt;std::uint8_t&gt;(prioSpec &amp; 0xFFU); // QF-prio.
m_pthre = 0U; // not used
register_(); // make QF aware of this QActive/QXThread
if (stkSto == nullptr) { // starting basic thread (AO)?
m_eQueue.init(qSto, qLen); // init the built-in queue
m_osObject = nullptr; // no private stack for AO
this-&gt;init(par, m_prio); // top-most initial tran. (virtual call)
QS_FLUSH(); // flush the trace buffer to the host
// see if this AO needs to be scheduled if QXK is already running
QF_CRIT_ENTRY();
QF_MEM_SYS();
if (QXK_priv_.lockCeil &lt;= QF_MAX_ACTIVE) { // scheduler running?
if (QXK_sched_() != 0U) { // activation needed?
QXK_activate_(); // synchronously activate basic-thred(s)
}
}
QF_MEM_APP();
QF_CRIT_EXIT();
}
else { // starting QXThread
// is storage for the queue buffer provided?
if (qSto != nullptr) {
m_eQueue.init(qSto, qLen);
}
// extended threads provide their thread function in place of
// the top-most initial tran. 'm_temp.act'
QXK_PTR_CAST_(QXThread*, this)-&gt;stackInit_(m_temp.thr,
stkSto, stkSize);
// the new thread is not blocked on any object
m_temp.obj = nullptr;
QF_CRIT_ENTRY();
QF_MEM_SYS();
// extended-thread becomes ready immediately
QXK_priv_.readySet.insert(static_cast&lt;std::uint_fast8_t&gt;(m_prio));
#ifndef Q_UNSAFE
QXK_priv_.readySet.update_(&amp;QXK_priv_.readySet_dis);
#endif
// see if this thread needs to be scheduled in case QXK is running
if (QXK_priv_.lockCeil &lt;= QF_MAX_ACTIVE) {
static_cast&lt;void&gt;(QXK_sched_()); // schedule other threads
}
QF_MEM_APP();
QF_CRIT_EXIT();
}</code>
</operation>
</class>
</package>
<!--${QXK-extern-C}-->
<package name="QXK-extern-C" stereotype="0x02">
<!--${QXK-extern-C::QXK_Attr}-->
<class name="QXK_Attr">
<!--${QXK-extern-C::QXK_Attr::curr}-->
<attribute name="curr" type="QP::QActive * volatile" visibility="0x00" properties="0x00"/>
<!--${QXK-extern-C::QXK_Attr::next}-->
<attribute name="next" type="QP::QActive * volatile" visibility="0x00" properties="0x00"/>
<!--${QXK-extern-C::QXK_Attr::prev}-->
<attribute name="prev" type="QP::QActive * volatile" visibility="0x00" properties="0x00"/>
<!--${QXK-extern-C::QXK_Attr::actPrio}-->
<attribute name="actPrio" type="std::uint_fast8_t volatile" visibility="0x00" properties="0x00"/>
<!--${QXK-extern-C::QXK_Attr::lockCeil}-->
<attribute name="lockCeil" type="std::uint_fast8_t volatile" visibility="0x00" properties="0x00"/>
<!--${QXK-extern-C::QXK_Attr::lockHolder}-->
<attribute name="lockHolder" type="std::uint_fast8_t volatile" visibility="0x00" properties="0x00"/>
<!--${QXK-extern-C::QXK_Attr::readySet}-->
<attribute name="readySet" type="QP::QPSet" visibility="0x00" properties="0x00"/>
<!--${QXK-extern-C::QXK_Attr::readySet_dis}-->
<attribute name="readySet_dis?ndef Q_UNSAFE" type="QP::QPSet" visibility="0x00" properties="0x00"/>
</class>
<!--${QXK-extern-C::QXK_priv_}-->
<attribute name="QXK_priv_" type="QXK_Attr" visibility="0x00" properties="0x00"/>
<!--${QXK-extern-C::QXK_sched_}-->
<operation name="QXK_sched_" type="std::uint_fast8_t" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>Q_INVARIANT_INCRIT(402,
QXK_priv_.readySet.verify_(&amp;QXK_priv_.readySet_dis));
std::uint_fast8_t p;
if (QXK_priv_.readySet.isEmpty()) {
p = 0U; // no activation needed
}
else {
// find the highest-prio thread ready to run
p = QXK_priv_.readySet.findMax();
if (p &lt;= QXK_priv_.lockCeil) {
// prio. of the thread holding the lock
p = static_cast&lt;std::uint_fast8_t&gt;(
QP::QActive::registry_[QXK_priv_.lockHolder]-&gt;getPrio());
if (p != 0U) {
Q_ASSERT_INCRIT(410, QXK_priv_.readySet.hasElement(p));
}
}
}
QP::QActive const * const curr = QXK_priv_.curr;
QP::QActive * const next = QP::QActive::registry_[p];
// the next thread found must be registered in QF
Q_ASSERT_INCRIT(420, next != nullptr);
// is the current thread a basic-thread?
if (curr == nullptr) {
// is the new prio. above the active prio.?
if (p &gt; QXK_priv_.actPrio) {
QXK_priv_.next = next; // set the next AO to activate
if (next-&gt;getOsObject() != nullptr) { // is next extended?
QXK_CONTEXT_SWITCH_();
p = 0U; // no activation needed
}
}
else { // below the active prio.
QXK_priv_.next = nullptr;
p = 0U; // no activation needed
}
}
else { // currently executing an extended-thread
// is the current thread different from the next?
if (curr != next) {
QXK_priv_.next = next;
QXK_CONTEXT_SWITCH_();
}
else { // current is the same as next
QXK_priv_.next = nullptr; // no need to context-switch
}
p = 0U; // no activation needed
}
return p;</code>
</operation>
<!--${QXK-extern-C::QXK_activate_}-->
<operation name="QXK_activate_" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>std::uint_fast8_t const prio_in = QXK_priv_.actPrio;
QP::QActive *next = QXK_priv_.next; // the next AO (basic-thread) to run
Q_REQUIRE_INCRIT(500, (next != nullptr) &amp;&amp; (prio_in &lt;= QF_MAX_ACTIVE));
// QXK Context switch callback defined or QS tracing enabled?
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
QXK_contextSw_(next);
#endif // QF_ON_CONTEXT_SW || Q_SPY
QXK_priv_.next = nullptr; // clear the next AO
QXK_priv_.curr = nullptr; // current is basic-thread
// prio. of the next thread
std::uint_fast8_t p = next-&gt;getPrio();
// loop until no more ready-to-run AOs of higher prio than the initial
do {
QXK_priv_.actPrio = p; // next active prio
QF_MEM_APP();
QF_INT_ENABLE(); // unconditionally enable interrupts
QP::QEvt const * const e = next-&gt;get_();
// NOTE QActive::get_() performs QS_MEM_APP() before return
// dispatch event (virtual call)
next-&gt;dispatch(e, next-&gt;getPrio());
#if (QF_MAX_EPOOL &gt; 0U)
QP::QF::gc(e);
#endif
QF_INT_DISABLE(); // unconditionally disable interrupts
QF_MEM_SYS();
// check internal integrity (duplicate inverse storage)
Q_INVARIANT_INCRIT(502,
QXK_priv_.readySet.verify_(&amp;QXK_priv_.readySet_dis));
if (next-&gt;getEQueue().isEmpty()) { // empty queue?
QXK_priv_.readySet.remove(p);
#ifndef Q_UNSAFE
QXK_priv_.readySet.update_(&amp;QXK_priv_.readySet_dis);
#endif
}
if (QXK_priv_.readySet.isEmpty()) {
QXK_priv_.next = nullptr;
next = QP::QActive::registry_[0];
p = 0U; // no activation needed
}
else {
// find next highest-prio below the lock ceiling
p = QXK_priv_.readySet.findMax();
if (p &lt;= QXK_priv_.lockCeil) {
p = QXK_priv_.lockHolder;
if (p != 0U) {
Q_ASSERT_INCRIT(510, QXK_priv_.readySet.hasElement(p));
}
}
// set the next thread and ensure that it is registered
next = QP::QActive::registry_[p];
Q_ASSERT_INCRIT(520, next != nullptr);
// is next a basic thread?
if (next-&gt;getOsObject() == nullptr) {
// is the next prio. above the initial prio.?
if (p &gt; QP::QActive::registry_[prio_in]-&gt;getPrio()) {
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
if (p != QXK_priv_.actPrio) { // changing threads?
QXK_contextSw_(next);
}
#endif // QF_ON_CONTEXT_SW || Q_SPY
QXK_priv_.next = next;
}
else {
QXK_priv_.next = nullptr;
p = 0U; // no activation needed
}
}
else { // next is the extended-thread
QXK_priv_.next = next;
QXK_CONTEXT_SWITCH_();
p = 0U; // no activation needed
}
}
} while (p != 0U); // while activation needed
// restore the active prio.
QXK_priv_.actPrio = prio_in;
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
if (next-&gt;getOsObject() == nullptr) {
QXK_contextSw_((prio_in == 0U)
? nullptr
: QP::QActive::registry_[prio_in]);
}
#endif // QF_ON_CONTEXT_SW || Q_SPY</code>
</operation>
<!--${QXK-extern-C::QXK_contextSw_}-->
<operation name="QXK_contextSw_" type="void" visibility="0x00" properties="0x00">
<!--${QXK-extern-C::QXK_contextSw_::next}-->
<parameter name="next" type="QP::QActive * const"/>
<code>#ifdef Q_SPY
std::uint_fast8_t const prev_prio = (QXK_priv_.prev != nullptr)
? QXK_priv_.prev-&gt;getPrio()
: 0U;
if (next != nullptr) { // next is NOT idle?
std::uint_fast8_t const next_prio = next-&gt;getPrio();
QS_BEGIN_PRE_(QP::QS_SCHED_NEXT, next_prio)
QS_TIME_PRE_(); // timestamp
QS_2U8_PRE_(next_prio, prev_prio);
QS_END_PRE_()
}
else { // going to idle
QS_BEGIN_PRE_(QP::QS_SCHED_IDLE, prev_prio)
QS_TIME_PRE_(); // timestamp
QS_U8_PRE_(prev_prio);
QS_END_PRE_()
}
#endif // Q_SPY
#ifdef QF_ON_CONTEXT_SW
QF_onContextSw(QXK_priv_.prev, next);
#endif // QF_ON_CONTEXT_SW
QXK_priv_.prev = next; // update the previous thread</code>
</operation>
<!--${QXK-extern-C::QXK_threadExit_}-->
<operation name="QXK_threadExit_" type="void" visibility="0x00" properties="0x00">
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QP::QXThread const * const thr = QXTHREAD_CAST_(QXK_priv_.curr);
Q_REQUIRE_INCRIT(900, (!QXK_ISR_CONTEXT_())
&amp;&amp; (thr != nullptr)); // current thread must be extended
Q_REQUIRE_INCRIT(901, QXK_priv_.lockHolder != thr-&gt;getPrio());
std::uint_fast8_t const p =
static_cast&lt;std::uint_fast8_t&gt;(thr-&gt;getPrio());
QF_MEM_SYS();
QP::QActive::registry_[p] = nullptr;
QXK_priv_.readySet.remove(p);
#ifndef Q_UNSAFE
QXK_priv_.readySet.update_(&amp;QXK_priv_.readySet_dis);
#endif
static_cast&lt;void&gt;(QXK_sched_()); // schedule other threads
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
</package>
<!--${QXK-impl}-->
<package name="QXK-impl" stereotype="0x02">
<!--${QXK-impl::QF_SCHED_STAT_}-->
<attribute name="QF_SCHED_STAT_" type="" visibility="0x03" properties="0x00">
<code>QSchedStatus lockStat_;</code>
</attribute>
<!--${QXK-impl::QF_SCHED_LOCK_}-->
<operation name="QF_SCHED_LOCK_" type="" visibility="0x03" properties="0x00">
<!--${QXK-impl::QF_SCHED_LOCK_::ceil_}-->
<parameter name="ceil_" type="std::uint_fast8_t"/>
<code>do { \
if (QXK_ISR_CONTEXT_()) { \
lockStat_ = 0xFFU; \
} else { \
lockStat_ = QXK::schedLock((ceil_)); \
} \
} while (false)</code>
</operation>
<!--${QXK-impl::QF_SCHED_UNLOCK_}-->
<operation name="QF_SCHED_UNLOCK_" type="" visibility="0x03" properties="0x00">
<code>do { \
if (lockStat_ != 0xFFU) { \
QXK::schedUnlock(lockStat_); \
} \
} while (false)</code>
</operation>
<!--${QXK-impl::QACTIVE_EQUEUE_WAIT_}-->
<operation name="QACTIVE_EQUEUE_WAIT_" type="" visibility="0x03" properties="0x00">
<documentation>// QXK native event queue waiting</documentation>
<!--${QXK-impl::QACTIVE_EQUEUE_W~::me_}-->
<parameter name="me_" type="QP::QActive *"/>
<code>\
Q_ASSERT_INCRIT(310, (me_)-&gt;m_eQueue.m_frontEvt != nullptr)</code>
</operation>
<!--${QXK-impl::QACTIVE_EQUEUE_SIGNAL_}-->
<operation name="QACTIVE_EQUEUE_SIGNAL_?ndef Q_UNSAFE" type="" visibility="0x03" properties="0x00">
<documentation>// QXK native event queue signalling</documentation>
<!--${QXK-impl::QACTIVE_EQUEUE_S~::me_}-->
<parameter name="me_" type="QP::QActive *"/>
<code>do { \
QXK_priv_.readySet.insert( \
static_cast&lt;std::uint_fast8_t&gt;((me_)-&gt;m_prio)); \
QXK_priv_.readySet.update_(&amp;QXK_priv_.readySet_dis); \
if (!QXK_ISR_CONTEXT_()) { \
if (QXK_sched_() != 0U) { \
QXK_activate_(); \
} \
} \
} while (false)</code>
</operation>
<!--${QXK-impl::QACTIVE_EQUEUE_SIGNAL_}-->
<operation name="QACTIVE_EQUEUE_SIGNAL_?def Q_UNSAFE" type="" visibility="0x03" properties="0x00">
<documentation>// QXK native event queue signalling</documentation>
<!--${QXK-impl::QACTIVE_EQUEUE_S~::me_}-->
<parameter name="me_" type="QP::QActive *"/>
<code>do { \
QXK_priv_.readySet.insert( \
static_cast&lt;std::uint_fast8_t&gt;((me_)-&gt;m_prio)); \
if (!QXK_ISR_CONTEXT_()) { \
if (QXK_sched_() != 0U) { \
QXK_activate_(); \
} \
} \
} while (false)</code>
</operation>
<!--${QXK-impl::QXTHREAD_EQUEUE_SIGNAL_}-->
<operation name="QXTHREAD_EQUEUE_SIGNAL_?ndef Q_UNSAFE" type="" visibility="0x03" properties="0x00">
<!--${QXK-impl::QXTHREAD_EQUEUE_~::me_}-->
<parameter name="me_" type="QP::QActive *"/>
<code>do { \
if ((me_)-&gt;m_temp.obj == QXK_PTR_CAST_(QMState*, &amp;(me_)-&gt;m_eQueue)) { \
static_cast&lt;void&gt;(QXTHREAD_CAST_(me_)-&gt;teDisarm_()); \
QXK_priv_.readySet.insert( \
static_cast&lt;std::uint_fast8_t&gt;((me_)-&gt;m_prio)); \
QXK_priv_.readySet.update_(&amp;QXK_priv_.readySet_dis); \
if (!QXK_ISR_CONTEXT_()) { \
static_cast&lt;void&gt;(QXK_sched_()); \
} \
} \
} while (false)</code>
</operation>
<!--${QXK-impl::QXTHREAD_EQUEUE_SIGNAL_}-->
<operation name="QXTHREAD_EQUEUE_SIGNAL_?def Q_UNSAFE" type="" visibility="0x03" properties="0x00">
<!--${QXK-impl::QXTHREAD_EQUEUE_~::me_}-->
<parameter name="me_" type="QActive *"/>
<code>do { \
if ((me_)-&gt;m_temp.obj == QXK_PTR_CAST_(QMState*, &amp;(me_)-&gt;m_eQueue)) { \
static_cast&lt;void&gt;(QXTHREAD_CAST_(me_)-&gt;teDisarm_()); \
QXK_priv_.readySet.insert( \
static_cast&lt;std::uint_fast8_t&gt;((me_)-&gt;m_prio)); \
if (!QXK_ISR_CONTEXT_()) { \
static_cast&lt;void&gt;(QXK_sched_()); \
} \
} \
} while (false)</code>
</operation>
<!--${QXK-impl::QXTHREAD_CAST_}-->
<operation name="QXTHREAD_CAST_" type="QXThread *" visibility="0x03" properties="0x00">
<!--${QXK-impl::QXTHREAD_CAST_::ptr_}-->
<parameter name="ptr_" type="QP::QActive *"/>
<code>(static_cast&lt;QP::QXThread *&gt;(ptr_))</code>
</operation>
<!--${QXK-impl::QXK_PTR_CAST_}-->
<operation name="QXK_PTR_CAST_" type="QXThread *" visibility="0x03" properties="0x00">
<specifiers>&lt;type_&gt;</specifiers>
<!--${QXK-impl::QXK_PTR_CAST_::type_}-->
<parameter name="type_" type="&lt;QXK obj&gt;"/>
<!--${QXK-impl::QXK_PTR_CAST_::ptr_}-->
<parameter name="ptr_" type="QP::QActive *"/>
<code>(reinterpret_cast&lt;type_&gt;(ptr_))</code>
</operation>
</package>
<!--${QS}-->
<package name="QS" stereotype="0x05" namespace="QP::">
<!--${QS::types}-->
<package name="types" stereotype="0x02">
<!--${QS::types::QSpyPre}-->
<attribute name="QSpyPre" type="enum" visibility="0x04" properties="0x00">
<documentation>//! pre-defined QS record IDs</documentation>
<code>: std::int8_t {
// [0] QS session (not maskable)
QS_EMPTY, //!&lt; QS record for cleanly starting a session
// [1] SM records
QS_QEP_STATE_ENTRY, //!&lt; a state was entered
QS_QEP_STATE_EXIT, //!&lt; a state was exited
QS_QEP_STATE_INIT, //!&lt; an initial transition was taken in a state
QS_QEP_INIT_TRAN, //!&lt; the top-most initial transition was taken
QS_QEP_INTERN_TRAN, //!&lt; an internal transition was taken
QS_QEP_TRAN, //!&lt; a regular transition was taken
QS_QEP_IGNORED, //!&lt; an event was ignored (silently discarded)
QS_QEP_DISPATCH, //!&lt; an event was dispatched (begin of RTC step)
QS_QEP_UNHANDLED, //!&lt; an event was un-handled due to a guard
// [10] Active Object (AO) records
QS_QF_ACTIVE_DEFER, //!&lt; AO deferred an event
QS_QF_ACTIVE_RECALL, //!&lt; AO recalled an event
QS_QF_ACTIVE_SUBSCRIBE, //!&lt; an AO subscribed to an event
QS_QF_ACTIVE_UNSUBSCRIBE, //!&lt; an AO unsubscribed to an event
QS_QF_ACTIVE_POST, //!&lt; an event was posted (FIFO) directly to AO
QS_QF_ACTIVE_POST_LIFO, //!&lt; an event was posted (LIFO) directly to AO
QS_QF_ACTIVE_GET, //!&lt; AO got an event and its queue is not empty
QS_QF_ACTIVE_GET_LAST,//!&lt; AO got an event and its queue is empty
QS_QF_ACTIVE_RECALL_ATTEMPT, //!&lt; AO attempted to recall an event
// [19] Event Queue (EQ) records
QS_QF_EQUEUE_POST, //!&lt; an event was posted (FIFO) to a raw queue
QS_QF_EQUEUE_POST_LIFO, //!&lt; an event was posted (LIFO) to a raw queue
QS_QF_EQUEUE_GET, //!&lt; get an event and queue still not empty
QS_QF_EQUEUE_GET_LAST,//!&lt; get the last event from the queue
// [23] Framework (QF) records
QS_QF_NEW_ATTEMPT, //!&lt; an attempt to allocate an event failed
// [24] Memory Pool (MP) records
QS_QF_MPOOL_GET, //!&lt; a memory block was removed from memory pool
QS_QF_MPOOL_PUT, //!&lt; a memory block was returned to memory pool
// [26] Additional Framework (QF) records
QS_QF_PUBLISH, //!&lt; an event was published to active objects
QS_QF_NEW_REF, //!&lt; new event reference was created
QS_QF_NEW, //!&lt; new event was created
QS_QF_GC_ATTEMPT, //!&lt; garbage collection attempt
QS_QF_GC, //!&lt; garbage collection
QS_QF_TICK, //!&lt; QTimeEvt tick was called
// [32] Time Event (TE) records
QS_QF_TIMEEVT_ARM, //!&lt; a time event was armed
QS_QF_TIMEEVT_AUTO_DISARM, //!&lt; a time event expired and was disarmed
QS_QF_TIMEEVT_DISARM_ATTEMPT,//!&lt; attempt to disarm a disarmed QTimeEvt
QS_QF_TIMEEVT_DISARM, //!&lt; true disarming of an armed time event
QS_QF_TIMEEVT_REARM, //!&lt; rearming of a time event
QS_QF_TIMEEVT_POST, //!&lt; a time event posted itself directly to an AO
// [38] Additional Framework (QF) records
QS_QF_DELETE_REF, //!&lt; an event reference is about to be deleted
QS_QF_CRIT_ENTRY, //!&lt; critical section was entered
QS_QF_CRIT_EXIT, //!&lt; critical section was exited
QS_QF_ISR_ENTRY, //!&lt; an ISR was entered
QS_QF_ISR_EXIT, //!&lt; an ISR was exited
QS_QF_INT_DISABLE, //!&lt; interrupts were disabled
QS_QF_INT_ENABLE, //!&lt; interrupts were enabled
// [45] Additional Active Object (AO) records
QS_QF_ACTIVE_POST_ATTEMPT,//!&lt; attempt to post an evt to AO failed
// [46] Additional Event Queue (EQ) records
QS_QF_EQUEUE_POST_ATTEMPT,//!&lt; attempt to post evt to QEQueue failed
// [47] Additional Memory Pool (MP) records
QS_QF_MPOOL_GET_ATTEMPT, //!&lt; attempt to get a memory block failed
// [48] Scheduler (SC) records
QS_SCHED_PREEMPT, //!&lt; scheduler asynchronously preempted a task
QS_SCHED_RESTORE, //!&lt; scheduler restored preempted task
QS_SCHED_LOCK, //!&lt; scheduler was locked
QS_SCHED_UNLOCK, //!&lt; scheduler was unlocked
QS_SCHED_NEXT, //!&lt; scheduler started next task
QS_SCHED_IDLE, //!&lt; scheduler restored the idle task
// [54] Miscellaneous QS records (not maskable)
QS_ENUM_DICT, //!&lt; enumeration dictionary entry
// [55] Additional QEP records
QS_QEP_TRAN_HIST, //!&lt; a tran to history was taken
QS_QEP_TRAN_EP, //!&lt; a tran to entry point into a submachine
QS_QEP_TRAN_XP, //!&lt; a tran to exit point out of a submachine
// [58] Miscellaneous QS records (not maskable)
QS_TEST_PAUSED, //!&lt; test has been paused
QS_TEST_PROBE_GET, //!&lt; reports that Test-Probe has been used
QS_SIG_DICT, //!&lt; signal dictionary entry
QS_OBJ_DICT, //!&lt; object dictionary entry
QS_FUN_DICT, //!&lt; function dictionary entry
QS_USR_DICT, //!&lt; user QS record dictionary entry
QS_TARGET_INFO, //!&lt; reports the Target information
QS_TARGET_DONE, //!&lt; reports completion of a user callback
QS_RX_STATUS, //!&lt; reports QS data receive status
QS_QUERY_DATA, //!&lt; reports the data from &quot;current object&quot; query
QS_PEEK_DATA, //!&lt; reports the data from the PEEK query
QS_ASSERT_FAIL, //!&lt; assertion failed in the code
QS_QF_RUN, //!&lt; QF_run() was entered
// [71] Semaphore (SEM) records
QS_SEM_TAKE, //!&lt; a semaphore was taken by a thread
QS_SEM_BLOCK, //!&lt; a semaphore blocked a thread
QS_SEM_SIGNAL, //!&lt; a semaphore was signaled
QS_SEM_BLOCK_ATTEMPT, //!&lt; a semaphore blocked was attempted
// [75] Mutex (MTX) records
QS_MTX_LOCK, //!&lt; a mutex was locked
QS_MTX_BLOCK, //!&lt; a mutex blocked a thread
QS_MTX_UNLOCK, //!&lt; a mutex was unlocked
QS_MTX_LOCK_ATTEMPT, //!&lt; a mutex lock was attempted
QS_MTX_BLOCK_ATTEMPT, //!&lt; a mutex blocking was attempted
QS_MTX_UNLOCK_ATTEMPT,//!&lt; a mutex unlock was attempted
// [81]
QS_PRE_MAX //!&lt; the # predefined signals
};</code>
</attribute>
<!--${QS::types::QSpyGroups}-->
<attribute name="QSpyGroups" type="enum" visibility="0x04" properties="0x00">
<documentation>//! QS-TX record groups for QS_GLB_FILTER()</documentation>
<code>: std::int16_t {
QS_ALL_RECORDS = 0xF0,//!&lt; all maskable QS records
QS_SM_RECORDS, //!&lt; State Machine QS records
QS_AO_RECORDS, //!&lt; Active Object QS records
QS_EQ_RECORDS, //!&lt; Event Queues QS records
QS_MP_RECORDS, //!&lt; Memory Pools QS records
QS_TE_RECORDS, //!&lt; Time Events QS records
QS_QF_RECORDS, //!&lt; QF QS records
QS_SC_RECORDS, //!&lt; Scheduler QS records
QS_SEM_RECORDS, //!&lt; Semaphore QS records
QS_MTX_RECORDS, //!&lt; Mutex QS records
QS_U0_RECORDS, //!&lt; User Group 100-104 records
QS_U1_RECORDS, //!&lt; User Group 105-109 records
QS_U2_RECORDS, //!&lt; User Group 110-114 records
QS_U3_RECORDS, //!&lt; User Group 115-119 records
QS_U4_RECORDS, //!&lt; User Group 120-124 records
QS_UA_RECORDS //!&lt; All User records
};</code>
</attribute>
<!--${QS::types::QSpyUserOffsets}-->
<attribute name="QSpyUserOffsets" type="enum" visibility="0x04" properties="0x00">
<documentation>//! QS user record group offsets for QS_GLB_FILTER()</documentation>
<code>: std::int16_t {
QS_USER = 100, //!&lt; the first record available to QS users
QS_USER0 = QS_USER, //!&lt; offset for User Group 0
QS_USER1 = QS_USER0 + 5, //!&lt; offset for User Group 1
QS_USER2 = QS_USER1 + 5, //!&lt; offset for User Group 2
QS_USER3 = QS_USER2 + 5, //!&lt; offset for User Group 3
QS_USER4 = QS_USER3 + 5 //!&lt; offset for User Group 4
};</code>
</attribute>
<!--${QS::types::QSpyIdOffsets}-->
<attribute name="QSpyIdOffsets" type="enum" visibility="0x04" properties="0x00">
<documentation>//! QS ID offsets for QS_LOC_FILTER()</documentation>
<code>: std::int16_t {
QS_AO_ID = 0, //!&lt; offset for AO priorities
QS_EP_ID = 64, //!&lt; offset for event-pool IDs
QS_EQ_ID = 80, //!&lt; offset for event-queue IDs
QS_AP_ID = 96 //!&lt; offset for Application-specific IDs
};</code>
</attribute>
<!--${QS::types::QSpyIdGroups}-->
<attribute name="QSpyIdGroups" type="enum" visibility="0x04" properties="0x00">
<documentation>//! QS ID groups for QS_LOC_FILTER()</documentation>
<code>: std::int16_t {
QS_ALL_IDS = 0xF0, //!&lt; all QS IDs
QS_AO_IDS = 0x80 + QS_AO_ID, //!&lt; AO IDs (priorities)
QS_EP_IDS = 0x80 + QS_EP_ID, //!&lt; event-pool IDs
QS_EQ_IDS = 0x80 + QS_EQ_ID, //!&lt; event-queue IDs
QS_AP_IDS = 0x80 + QS_AP_ID //!&lt; Application-specific IDs
};</code>
</attribute>
<!--${QS::types::QSpyId}-->
<attribute name="QSpyId" type="struct" visibility="0x04" properties="0x00">
<code>{
std::uint8_t m_prio; //!&lt; prio. (qsId) for the QS &quot;local filter&quot;
// get the prio. (qsId) from the QSpyId object
std::uint_fast8_t getPrio() const noexcept {
return static_cast&lt;std::uint_fast8_t&gt;(m_prio);
}
};</code>
</attribute>
<!--${QS::types::QSObj}-->
<attribute name="QSObj? (QS_OBJ_PTR_SIZE == 2U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint16_t;</code>
</attribute>
<!--${QS::types::QSObj}-->
<attribute name="QSObj? (QS_OBJ_PTR_SIZE == 4U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint32_t;</code>
</attribute>
<!--${QS::types::QSObj}-->
<attribute name="QSObj? (QS_OBJ_PTR_SIZE == 8U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint64_t;</code>
</attribute>
<!--${QS::types::QSFun}-->
<attribute name="QSFun? (QS_FUN_PTR_SIZE == 2U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint16_t;</code>
</attribute>
<!--${QS::types::QSFun}-->
<attribute name="QSFun? (QS_FUN_PTR_SIZE == 4U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint32_t;</code>
</attribute>
<!--${QS::types::QSFun}-->
<attribute name="QSFun? (QS_FUN_PTR_SIZE == 8U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint64_t;</code>
</attribute>
<!--${QS::types::QSpyFunPtr}-->
<attribute name="QSpyFunPtr" type="using" visibility="0x04" properties="0x01">
<code>= void (*)();</code>
</attribute>
<!--${QS::types::QSCtr}-->
<attribute name="QSCtr? (QS_CTR_SIZE == 2U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint16_t;</code>
</attribute>
<!--${QS::types::QSCtr}-->
<attribute name="QSCtr? (QS_CTR_SIZE == 4U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint32_t;</code>
</attribute>
<!--${QS::types::QSTimeCtr}-->
<attribute name="QSTimeCtr? (QS_TIME_SIZE == 2U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint16_t;</code>
</attribute>
<!--${QS::types::QSTimeCtr}-->
<attribute name="QSTimeCtr? (QS_TIME_SIZE == 4U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint32_t;</code>
</attribute>
</package>
<!--${QS::filters}-->
<package name="filters" stereotype="0x02" namespace="QS::">
<!--${QS::filters::Filter}-->
<class name="Filter">
<!--${QS::filters::Filter::glb[16]}-->
<attribute name="glb[16]" type="std::uint8_t" visibility="0x00" properties="0x00"/>
<!--${QS::filters::Filter::loc[16]}-->
<attribute name="loc[16]" type="std::uint8_t" visibility="0x00" properties="0x00"/>
</class>
<!--${QS::filters::filt_}-->
<attribute name="filt_" type="Filter" visibility="0x00" properties="0x01"/>
</package>
<!--${QS::QS-TX}-->
<package name="QS-TX" stereotype="0x02" namespace="QS::">
<!--${QS::QS-TX::preType}-->
<attribute name="preType" type="enum" visibility="0x04" properties="0x01">
<documentation>//! Enumerates data elements for app-specific trace records</documentation>
<code>: std::uint8_t {
I8_ENUM_T, //!&lt; signed 8-bit integer or enum format
U8_T, //!&lt; unsigned 8-bit integer format
I16_T, //!&lt; signed 16-bit integer format
U16_T, //!&lt; unsigned 16-bit integer format
I32_T, //!&lt; signed 32-bit integer format
U32_T, //!&lt; unsigned 32-bit integer format
F32_T, //!&lt; 32-bit floating point format
F64_T, //!&lt; 64-bit floating point format
STR_T, //!&lt; zero-terminated ASCII string format
MEM_T, //!&lt; up to 255-bytes memory block format
SIG_T, //!&lt; event signal format
OBJ_T, //!&lt; object pointer format
FUN_T, //!&lt; function pointer format
I64_T, //!&lt; signed 64-bit integer format
U64_T //!&lt; unsigned 64-bit integer format
};</code>
</attribute>
<!--${QS::QS-TX::force_cast}-->
<operation name="force_cast" type="template&lt;typename T_OUT, typename T_IN&gt; T_OUT" visibility="0x00" properties="0x02">
<!--${QS::QS-TX::force_cast::in}-->
<parameter name="in" type="T_IN"/>
<code>union TCast {
T_IN in;
T_OUT out;
} u = { in };
return u.out;</code>
</operation>
<!--${QS::QS-TX::initBuf}-->
<operation name="initBuf" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QS::QS-TX::initBuf::sto}-->
<parameter name="sto" type="std::uint8_t * const"/>
<!--${QS::QS-TX::initBuf::stoSize}-->
<parameter name="stoSize" type="std::uint_fast32_t const"/>
<code>priv_.buf = sto;
priv_.end = static_cast&lt;QSCtr&gt;(stoSize);
priv_.head = 0U;
priv_.tail = 0U;
priv_.used = 0U;
priv_.seq = 0U;
priv_.chksum = 0U;
priv_.critNest = 0U;
glbFilter_(-static_cast&lt;enum_t&gt;(QS_ALL_RECORDS));// all global filters OFF
locFilter_(static_cast&lt;enum_t&gt;(QS_ALL_IDS)); // all local filters ON
priv_.locFilter_AP = nullptr; // deprecated &quot;AP-filter&quot;
// produce an empty record to &quot;flush&quot; the QS trace buffer
beginRec_(QS_REC_NUM_(QS_EMPTY));
endRec_();
// produce the reset record to inform QSPY of a new session
target_info_pre_(0xFFU);
// hold off flushing after successful initialization (see QS_INIT())</code>
</operation>
<!--${QS::QS-TX::getByte}-->
<operation name="getByte" type="std::uint16_t" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>// NOTE: Must be called IN critical section.
// Also requires system-level memory access (QF_MEM_SYS()).
std::uint16_t ret;
if (priv_.used == 0U) {
ret = QS_EOD; // set End-Of-Data
}
else {
std::uint8_t const * const buf = priv_.buf; // put in a temporary
QSCtr tail = priv_.tail; // put in a temporary (register)
ret = static_cast&lt;std::uint16_t&gt;(buf[tail]); // set the byte to return
++tail; // advance the tail
if (tail == priv_.end) { // tail wrap around?
tail = 0U;
}
priv_.tail = tail; // update the tail
priv_.used = (priv_.used - 1U); // one less byte used
}
return ret; // return the byte or EOD</code>
</operation>
<!--${QS::QS-TX::getBlock}-->
<operation name="getBlock" type="std::uint8_t const *" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QS::QS-TX::getBlock::pNbytes}-->
<parameter name="pNbytes" type="std::uint16_t * const"/>
<code>// NOTE: Must be called IN critical section.
// Also requires system-level memory access (QF_MEM_SYS()).
QSCtr const used = priv_.used; // put in a temporary (register)
std::uint8_t *buf;
// any bytes used in the ring buffer?
if (used != 0U) {
QSCtr tail = priv_.tail; // put in a temporary (register)
QSCtr const end = priv_.end; // put in a temporary (register)
QSCtr n = static_cast&lt;QSCtr&gt;(end - tail);
if (n &gt; used) {
n = used;
}
if (n &gt; static_cast&lt;QSCtr&gt;(*pNbytes)) {
n = static_cast&lt;QSCtr&gt;(*pNbytes);
}
*pNbytes = static_cast&lt;std::uint16_t&gt;(n); // n-bytes available
buf = priv_.buf;
buf = &amp;buf[tail]; // the bytes are at the tail
priv_.used = static_cast&lt;QSCtr&gt;(used - n);
tail += n;
if (tail == end) {
tail = 0U;
}
priv_.tail = tail;
}
else { // no bytes available
*pNbytes = 0U; // no bytes available right now
buf = nullptr; // no bytes available right now
}
return buf;</code>
</operation>
<!--${QS::QS-TX::doOutput}-->
<operation name="doOutput" type="void" visibility="0x00" properties="0x00"/>
<!--${QS::QS-TX::onStartup}-->
<operation name="onStartup" type="bool" visibility="0x00" properties="0x00">
<!--${QS::QS-TX::onStartup::arg}-->
<parameter name="arg" type="void const *"/>
</operation>
<!--${QS::QS-TX::onCleanup}-->
<operation name="onCleanup" type="void" visibility="0x00" properties="0x00"/>
<!--${QS::QS-TX::onFlush}-->
<operation name="onFlush" type="void" visibility="0x00" properties="0x00"/>
<!--${QS::QS-TX::onGetTime}-->
<operation name="onGetTime" type="QSTimeCtr" visibility="0x00" properties="0x00"/>
</package>
<!--${QS::QS-RX}-->
<package name="QS-RX" stereotype="0x02" namespace="QS::">
<!--${QS::QS-RX::QSpyObjKind}-->
<attribute name="QSpyObjKind" type="enum" visibility="0x04" properties="0x01">
<documentation>//! Kinds of objects used QS-RX</documentation>
<code>: std::uint8_t {
SM_OBJ, //!&lt; state machine object
AO_OBJ, //!&lt; active object
MP_OBJ, //!&lt; event pool object
EQ_OBJ, //!&lt; raw queue object
TE_OBJ, //!&lt; time event object
AP_OBJ, //!&lt; generic Application-specific object
MAX_OBJ
};</code>
</attribute>
<!--${QS::QS-RX::OSpyObjCombnation}-->
<attribute name="OSpyObjCombnation" type="enum" visibility="0x04" properties="0x01">
<documentation>//! Object combinations for QS-RX</documentation>
<code>: std::uint8_t {
SM_AO_OBJ = MAX_OBJ //!&lt; combination of SM and AO
};</code>
</attribute>
<!--${QS::QS-RX::rxInitBuf}-->
<operation name="rxInitBuf" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QS::QS-RX::rxInitBuf::sto}-->
<parameter name="sto" type="std::uint8_t * const"/>
<!--${QS::QS-RX::rxInitBuf::stoSize}-->
<parameter name="stoSize" type="std::uint16_t const"/>
<code>rxPriv_.buf = &amp;sto[0];
rxPriv_.end = static_cast&lt;QSCtr&gt;(stoSize);
rxPriv_.head = 0U;
rxPriv_.tail = 0U;
rxPriv_.currObj[QS::SM_OBJ] = nullptr;
rxPriv_.currObj[QS::AO_OBJ] = nullptr;
rxPriv_.currObj[QS::MP_OBJ] = nullptr;
rxPriv_.currObj[QS::EQ_OBJ] = nullptr;
rxPriv_.currObj[QS::TE_OBJ] = nullptr;
rxPriv_.currObj[QS::AP_OBJ] = nullptr;
tran_(WAIT4_SEQ);
QP::QS::rxPriv_.esc = 0U;
QP::QS::rxPriv_.seq = 0U;
QP::QS::rxPriv_.chksum = 0U;
beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QS_OBJ_DICT));
QS_OBJ_PRE_(&amp;rxPriv_);
QS_STR_PRE_(&quot;QS_RX&quot;);
endRec_();
// no QS_REC_DONE(), because QS is not running yet
#ifdef Q_UTEST
tstPriv_.tpNum = 0U;
tstPriv_.testTime = 0U;
#endif // Q_UTEST</code>
</operation>
<!--${QS::QS-RX::rxPut}-->
<operation name="rxPut" type="bool" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QS::QS-RX::rxPut::b}-->
<parameter name="b" type="std::uint8_t const"/>
<code>// 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
}</code>
</operation>
<!--${QS::QS-RX::rxParse}-->
<operation name="rxParse" type="void" visibility="0x00" properties="0x00">
<code>QSCtr tail = rxPriv_.tail;
while (rxPriv_.head != tail) { // QS-RX buffer NOT empty?
std::uint8_t b = rxPriv_.buf[tail];
++tail;
if (tail == rxPriv_.end) {
tail = 0U;
}
rxPriv_.tail = tail; // update the tail to a *valid* index
if (QP::QS::rxPriv_.esc != 0U) { // escaped byte arrived?
QP::QS::rxPriv_.esc = 0U;
b ^= QS_ESC_XOR;
QP::QS::rxPriv_.chksum += b;
rxParseData_(b);
}
else if (b == QS_ESC) {
QP::QS::rxPriv_.esc = 1U;
}
else if (b == QS_FRAME) {
// get ready for the next frame
b = QP::QS::rxPriv_.state; // save the current state in b
QP::QS::rxPriv_.esc = 0U;
tran_(WAIT4_SEQ);
if (QP::QS::rxPriv_.chksum == QS_GOOD_CHKSUM) {
QP::QS::rxPriv_.chksum = 0U;
rxHandleGoodFrame_(b);
}
else { // bad checksum
QP::QS::rxPriv_.chksum = 0U;
rxReportError_(0x41U);
rxHandleBadFrame_(b);
}
}
else {
QP::QS::rxPriv_.chksum += b;
rxParseData_(b);
}
}</code>
</operation>
<!--${QS::QS-RX::setCurrObj}-->
<operation name="setCurrObj" type="void" visibility="0x00" properties="0x00">
<!--${QS::QS-RX::setCurrObj::obj_kind}-->
<parameter name="obj_kind" type="std::uint8_t const"/>
<!--${QS::QS-RX::setCurrObj::obj_ptr}-->
<parameter name="obj_ptr" type="void * const"/>
<code>QS_CRIT_STAT
QS_CRIT_ENTRY();
Q_REQUIRE_INCRIT(300, obj_kind &lt; Q_DIM(rxPriv_.currObj));
QS_MEM_SYS();
rxPriv_.currObj[obj_kind] = obj_ptr;
QS_MEM_APP();
QS_CRIT_EXIT();</code>
</operation>
<!--${QS::QS-RX::rxGetNfree}-->
<operation name="rxGetNfree" type="std::uint16_t" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>// NOTE: Must be called IN critical section.
// Also requires system-level memory access (QF_MEM_SYS()).
QSCtr const head = rxPriv_.head;
std::uint16_t nFree;
if (head == rxPriv_.tail) { // buffer empty?
nFree = static_cast&lt;std::uint16_t&gt;(rxPriv_.end - 1U);
}
else if (head &lt; rxPriv_.tail) {
nFree = static_cast&lt;std::uint16_t&gt;(rxPriv_.tail - head - 1U);
}
else {
nFree = static_cast&lt;std::uint16_t&gt;(rxPriv_.end + rxPriv_.tail
- head - 1U);
}
return nFree;</code>
</operation>
<!--${QS::QS-RX::doInput}-->
<operation name="doInput" type="void" visibility="0x00" properties="0x00"/>
<!--${QS::QS-RX::onReset}-->
<operation name="onReset" type="void" visibility="0x00" properties="0x00"/>
<!--${QS::QS-RX::onCommand}-->
<operation name="onCommand" type="void" visibility="0x00" properties="0x00">
<!--${QS::QS-RX::onCommand::cmdId}-->
<parameter name="cmdId" type="std::uint8_t"/>
<!--${QS::QS-RX::onCommand::param1}-->
<parameter name="param1" type="std::uint32_t"/>
<!--${QS::QS-RX::onCommand::param2}-->
<parameter name="param2" type="std::uint32_t"/>
<!--${QS::QS-RX::onCommand::param3}-->
<parameter name="param3" type="std::uint32_t"/>
</operation>
</package>
<!--${QS::QUTest}-->
<package name="QUTest" stereotype="0x02" namespace="QS::">
<!--${QS::QUTest::TProbe}-->
<attribute name="TProbe" type="struct" visibility="0x04" properties="0x00">
<code>{
QSFun addr;
std::uint32_t data;
std::uint8_t idx;
};</code>
</attribute>
<!--${QS::QUTest::onTestSetup}-->
<operation name="onTestSetup" type="void" visibility="0x00" properties="0x00"/>
<!--${QS::QUTest::onTestTeardown}-->
<operation name="onTestTeardown" type="void" visibility="0x00" properties="0x00"/>
<!--${QS::QUTest::onTestEvt}-->
<operation name="onTestEvt" type="void" visibility="0x00" properties="0x00">
<!--${QS::QUTest::onTestEvt::e}-->
<parameter name="e" type="QEvt *"/>
</operation>
<!--${QS::QUTest::onTestPost}-->
<operation name="onTestPost" type="void" visibility="0x00" properties="0x00">
<!--${QS::QUTest::onTestPost::sender}-->
<parameter name="sender" type="void const *"/>
<!--${QS::QUTest::onTestPost::recipient}-->
<parameter name="recipient" type="QActive *"/>
<!--${QS::QUTest::onTestPost::e}-->
<parameter name="e" type="QEvt const *"/>
<!--${QS::QUTest::onTestPost::status}-->
<parameter name="status" type="bool"/>
</operation>
<!--${QS::QUTest::onTestLoop}-->
<operation name="onTestLoop" type="void" visibility="0x00" properties="0x00"/>
</package>
<!--${QS::QUTest-stub}-->
<package name="QUTest-stub" stereotype="0x05">
<!--${QS::QUTest-stub::QF}-->
<package name="QF" stereotype="0x02" namespace="QF::">
<!--${QS::QUTest-stub::QF::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x01">
<code>// Clear the internal QF variables, so that the framework can start
// correctly even if the startup code fails to clear the uninitialized
// data (as is required by the C++ Standard).
bzero_(&amp;QF::priv_, sizeof(QF::priv_));
bzero_(&amp;QS::tstPriv_, sizeof(QS::tstPriv_));
bzero_(&amp;QActive::registry_[0], sizeof(QActive::registry_));
#ifndef Q_UNSAFE
QS::tstPriv_.readySet.update_(&amp;QS::tstPriv_.readySet_dis);
#endif</code>
</operation>
<!--${QS::QUTest-stub::QF::stop}-->
<operation name="stop" type="void" visibility="0x00" properties="0x01">
<code>QS::onReset();</code>
</operation>
<!--${QS::QUTest-stub::QF::run}-->
<operation name="run" type="int_t" visibility="0x00" properties="0x01">
<code>QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
// function dictionaries for the standard API
QS_FUN_DICTIONARY(&amp;QActive::post_);
QS_FUN_DICTIONARY(&amp;QActive::postLIFO);
QS_FUN_DICTIONARY(&amp;QS::processTestEvts_);
// produce the QS_QF_RUN trace record
QS_BEGIN_PRE_(QS_QF_RUN, 0U)
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();
QS::processTestEvts_(); // process all events posted so far
QS::onTestLoop(); // run the unit test
QS::onCleanup(); // application cleanup
return 0; // return no error</code>
</operation>
</package>
<!--${QS::QUTest-stub::QActive}-->
<class name="QActive" superclass="QEP::QAsm">
<!--${QS::QUTest-stub::QActive::start}-->
<operation name="start" type="void" visibility="0x00" properties="0x04">
<!--${QS::QUTest-stub::QActive::start::prioSpec}-->
<parameter name="prioSpec" type="QPrioSpec const"/>
<!--${QS::QUTest-stub::QActive::start::qSto}-->
<parameter name="qSto" type="QEvt const * * const"/>
<!--${QS::QUTest-stub::QActive::start::qLen}-->
<parameter name="qLen" type="std::uint_fast16_t const"/>
<!--${QS::QUTest-stub::QActive::start::stkSto}-->
<parameter name="stkSto" type="void * const"/>
<!--${QS::QUTest-stub::QActive::start::stkSize}-->
<parameter name="stkSize" type="std::uint_fast16_t const"/>
<!--${QS::QUTest-stub::QActive::start::par}-->
<parameter name="par" type="void const * const"/>
<code>Q_UNUSED_PAR(stkSto);
Q_UNUSED_PAR(stkSize);
m_prio = static_cast&lt;std::uint8_t&gt;(prioSpec &amp; 0xFFU); // QF-priol
m_pthre = static_cast&lt;std::uint8_t&gt;(prioSpec &gt;&gt; 8U); // preemption-thre.
register_(); // make QF aware of this AO
m_eQueue.init(qSto, qLen); // initialize QEQueue of this AO
this-&gt;init(par, m_prio); // take the top-most initial tran. (virtual)</code>
</operation>
<!--${QS::QUTest-stub::QActive::stop}-->
<operation name="stop?def QACTIVE_CAN_STOP" type="void" visibility="0x00" properties="0x00">
<code>unsubscribeAll(); // unsubscribe from all events
unregister_(); // remove this object from QF</code>
</operation>
</class>
<!--${QS::QUTest-stub::QTimeEvt}-->
<class name="QTimeEvt" superclass="QEP::QEvt">
<!--${QS::QUTest-stub::QTimeEvt::tick1_}-->
<operation name="tick1_" type="void" visibility="0x00" properties="0x01">
<!--${QS::QUTest-stub::QTimeEvt::tick1_::tickRate}-->
<parameter name="tickRate" type="std::uint_fast8_t const"/>
<!--${QS::QUTest-stub::QTimeEvt::tick1_::sender}-->
<parameter name="sender" type="void const * const"/>
<code>QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
QTimeEvt *prev = &amp;QTimeEvt::timeEvtHead_[tickRate];
QS_BEGIN_PRE_(QS_QF_TICK, 0U)
prev-&gt;m_ctr = (prev-&gt;m_ctr + 1U);
QS_TEC_PRE_(prev-&gt;m_ctr); // tick ctr
QS_U8_PRE_(tickRate); // tick rate
QS_END_PRE_()
// is current Time Event object provided?
QTimeEvt *t = static_cast&lt;QTimeEvt *&gt;(QS::rxPriv_.currObj[QS::TE_OBJ]);
if (t != nullptr) {
// the time event must be armed
Q_ASSERT_INCRIT(810, t-&gt;m_ctr != 0U);
QActive * const act = static_cast&lt;QActive *&gt;(t-&gt;m_act);
// the recipient AO must be provided
Q_ASSERT_INCRIT(820, act != nullptr);
// periodic time evt?
if (t-&gt;m_interval != 0U) {
t-&gt;m_ctr = t-&gt;m_interval; // rearm the time event
}
else { // one-shot time event: automatically disarm
t-&gt;m_ctr = 0U; // auto-disarm
// mark time event 't' as NOT linked
t-&gt;refCtr_ = static_cast&lt;std::uint8_t&gt;(t-&gt;refCtr_
&amp; static_cast&lt;std::uint8_t&gt;(~TE_IS_LINKED));
QS_BEGIN_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act-&gt;m_prio)
QS_OBJ_PRE_(t); // this time event object
QS_OBJ_PRE_(act); // the target AO
QS_U8_PRE_(tickRate); // tick rate
QS_END_PRE_()
}
QS_BEGIN_PRE_(QS_QF_TIMEEVT_POST, act-&gt;m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(t); // the time event object
QS_SIG_PRE_(t-&gt;sig); // signal of this time event
QS_OBJ_PRE_(act); // the target AO
QS_U8_PRE_(tickRate); // tick rate
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT(); // exit critical section before posting
// asserts if queue overflows
static_cast&lt;void&gt;(act-&gt;POST(t, sender));
QS_CRIT_ENTRY();
QS_MEM_SYS();
}
// update the linked list of time events
for (;;) {
t = prev-&gt;m_next; // advance down the time evt. list
// end of the list?
if (t == nullptr) {
// any new time events armed since the last run of tick()?
if (QTimeEvt::timeEvtHead_[tickRate].m_act != nullptr) {
// sanity check
Q_ASSERT_INCRIT(830, prev != nullptr);
prev-&gt;m_next = QTimeEvt::timeEvtHead_[tickRate].toTimeEvt();
QTimeEvt::timeEvtHead_[tickRate].m_act = nullptr;
t = prev-&gt;m_next; // switch to the new list
}
else {
break; // all currently armed time evts. processed
}
}
// time event scheduled for removal?
if (t-&gt;m_ctr == 0U) {
prev-&gt;m_next = t-&gt;m_next;
// mark time event 't' as NOT linked
t-&gt;refCtr_ = static_cast&lt;std::uint8_t&gt;(t-&gt;refCtr_
&amp; static_cast&lt;std::uint8_t&gt;(~TE_IS_LINKED));
// do NOT advance the prev pointer
QS_MEM_APP();
QS_CRIT_EXIT(); // exit crit. section to reduce latency
}
else {
prev = t; // advance to this time event
QS_MEM_APP();
QS_CRIT_EXIT(); // exit crit. section to reduce latency
}
QS_CRIT_ENTRY(); // re-enter crit. section to continue
QS_MEM_SYS();
}
QS_MEM_APP();
QS_CRIT_EXIT();</code>
</operation>
</class>
<!--${QS::QUTest-stub::QHsmDummy}-->
<class name="QHsmDummy" superclass="QEP::QAsm">
<!--${QS::QUTest-stub::QHsmDummy::QHsmDummy}-->
<operation name="QHsmDummy" type="" visibility="0x00" properties="0x00">
<code>: QAsm()</code>
</operation>
<!--${QS::QUTest-stub::QHsmDummy::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x00">
<specifiers>override</specifiers>
<!--${QS::QUTest-stub::QHsmDummy::init::e}-->
<parameter name="e" type="void const * const"/>
<!--${QS::QUTest-stub::QHsmDummy::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>Q_UNUSED_PAR(e);
#ifdef Q_SPY
if ((QS::priv_.flags &amp; 0x01U) == 0U) {
QS::priv_.flags |= 0x01U;
QS_FUN_DICTIONARY(&amp;QP::QHsm::top);
}
#else
Q_UNUSED_PAR(qsId);
#endif
QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId)
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(m_state.fun); // the source state
QS_FUN_PRE_(m_temp.fun); // the target of the initial tran.
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();</code>
</operation>
<!--${QS::QUTest-stub::QHsmDummy::dispatch}-->
<operation name="dispatch" type="void" visibility="0x00" properties="0x00">
<specifiers>override</specifiers>
<!--${QS::QUTest-stub::QHsmDummy::dispatch::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QS::QUTest-stub::QHsmDummy::dispatch::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId)
QS_TIME_PRE_(); // time stamp
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(m_state.fun); // the current state
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();</code>
</operation>
</class>
<!--${QS::QUTest-stub::QActiveDummy}-->
<class name="QActiveDummy" superclass="QF::QActive">
<!--${QS::QUTest-stub::QActiveDummy::QActive}-->
<attribute name="QActive" type="friend class" visibility="0x02" properties="0x00"/>
<!--${QS::QUTest-stub::QActiveDummy::QActiveDummy}-->
<operation name="QActiveDummy" type="" visibility="0x00" properties="0x00">
<code>: QActive(nullptr)</code>
</operation>
<!--${QS::QUTest-stub::QActiveDummy::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x00">
<specifiers>override</specifiers>
<!--${QS::QUTest-stub::QActiveDummy::init::e}-->
<parameter name="e" type="void const * const"/>
<!--${QS::QUTest-stub::QActiveDummy::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>Q_UNUSED_PAR(e);
Q_UNUSED_PAR(qsId);
#ifdef Q_SPY
if ((QS::priv_.flags &amp; 0x01U) == 0U) {
QS::priv_.flags |= 0x01U;
QS_FUN_DICTIONARY(&amp;QP::QHsm::top);
}
#endif
QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_STATE_INIT, m_prio)
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(m_state.fun); // the source state
QS_FUN_PRE_(m_temp.fun); // the target of the initial tran.
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();</code>
</operation>
<!--${QS::QUTest-stub::QActiveDummy::dispatch}-->
<operation name="dispatch" type="void" visibility="0x00" properties="0x00">
<specifiers>override</specifiers>
<!--${QS::QUTest-stub::QActiveDummy::dispatch::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QS::QUTest-stub::QActiveDummy::dispatch::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId)
QS_TIME_PRE_(); // time stamp
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_OBJ_PRE_(this); // this state machine object
QS_FUN_PRE_(m_state.fun); // the current state
QS_END_PRE_()
QS_MEM_APP();
QS_CRIT_EXIT();</code>
</operation>
<!--${QS::QUTest-stub::QActiveDummy::fakePost}-->
<operation name="fakePost" type="bool" visibility="0x02" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QS::QUTest-stub::QActiveDummy::fakePost::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QS::QUTest-stub::QActiveDummy::fakePost::margin}-->
<parameter name="margin" type="std::uint_fast16_t const"/>
<!--${QS::QUTest-stub::QActiveDummy::fakePost::sender}-->
<parameter name="sender" type="void const * const"/>
<code>QS_TEST_PROBE_DEF(&amp;QActive::post_)
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
// test-probe#1 for faking queue overflow
bool status = true;
QS_TEST_PROBE_ID(1,
status = false;
if (margin == QF::NO_MARGIN) {
// fake assertion Mod=qf_actq,Loc=110
Q_onError(&quot;qf_actq&quot;, 110);
}
)
// is it a mutable event?
if (e-&gt;getPoolNum_() != 0U) {
QEvt_refCtr_inc_(e);
}
std::uint_fast8_t const rec =
(status ? static_cast&lt;std::uint8_t&gt;(QS_QF_ACTIVE_POST)
: static_cast&lt;std::uint8_t&gt;(QS_QF_ACTIVE_POST_ATTEMPT));
QS_BEGIN_PRE_(rec, m_prio)
QS_TIME_PRE_(); // timestamp
QS_OBJ_PRE_(sender); // the sender object
QS_SIG_PRE_(e-&gt;sig); // the signal of the event
QS_OBJ_PRE_(this); // this active object
QS_2U8_PRE_(e-&gt;getPoolNum_(), e-&gt;refCtr_); // poolNum &amp; refCtr
QS_EQC_PRE_(0U); // # free entries
QS_EQC_PRE_(margin); // margin requested
QS_END_PRE_()
// callback to examine the posted event under the same conditions
// as producing the #QS_QF_ACTIVE_POST trace record, which are:
// the local filter for this AO ('m_prio') is set
if (QS_LOC_CHECK_(m_prio)) {
QS::onTestPost(sender, this, e, status);
}
QF_MEM_APP();
QF_CRIT_EXIT();
// recycle the event immediately, because it was not really posted
#if (QF_MAX_EPOOL &gt; 0U)
QF::gc(e);
#endif
return status;</code>
</operation>
<!--${QS::QUTest-stub::QActiveDummy::fakePostLIFO}-->
<operation name="fakePostLIFO" type="void" visibility="0x02" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QS::QUTest-stub::QActiveDummy::fakePostLIFO::e}-->
<parameter name="e" type="QEvt const * const"/>
<code>QS_TEST_PROBE_DEF(&amp;QActive::postLIFO)
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
// test-probe#1 for faking queue overflow
QS_TEST_PROBE_ID(1,
// fake assertion Mod=qf_actq,Loc=210
Q_onError(&quot;qf_actq&quot;, 210);
)
// is it a mutable event?
if (e-&gt;getPoolNum_() != 0U) {
QEvt_refCtr_inc_(e);
}
QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, m_prio)
QS_TIME_PRE_(); // timestamp
QS_SIG_PRE_(e-&gt;sig); // the signal of this event
QS_OBJ_PRE_(this); // this active object
QS_2U8_PRE_(e-&gt;getPoolNum_(), e-&gt;refCtr_); // poolNum &amp; refCtr
QS_EQC_PRE_(0U); // # free entries
QS_EQC_PRE_(0U); // min # free entries
QS_END_PRE_()
// callback to examine the posted event under the same conditions
// as producing the #QS_QF_ACTIVE_POST trace record, which are:
// the local filter for this AO ('m_prio') is set
if (QS_LOC_CHECK_(m_prio)) {
QS::onTestPost(nullptr, this, e, true);
}
QF_MEM_APP();
QF_CRIT_EXIT();
// recycle the event immediately, because it was not really posted
#if (QF_MAX_EPOOL &gt; 0U)
QF::gc(e);
#endif</code>
</operation>
</class>
</package>
</package>
<!--${QS-macros}-->
<package name="QS-macros" stereotype="0x02">
<!--${QS-macros::QS_INIT}-->
<operation name="QS_INIT" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_INIT::arg_}-->
<parameter name="arg_" type="void *"/>
<code>(QP::QS::onStartup(arg_))</code>
</operation>
<!--${QS-macros::QS_EXIT}-->
<operation name="QS_EXIT" type="void" visibility="0x03" properties="0x00">
<code>(QP::QS::onCleanup())</code>
</operation>
<!--${QS-macros::QS_OUTPUT}-->
<operation name="QS_OUTPUT" type="void" visibility="0x03" properties="0x00">
<code>(QP::QS::doOutput())</code>
</operation>
<!--${QS-macros::QS_RX_INPUT}-->
<operation name="QS_RX_INPUT" type="void" visibility="0x03" properties="0x00">
<code>(QP::QS::doInput())</code>
</operation>
<!--${QS-macros::QS_GLB_FILTER}-->
<operation name="QS_GLB_FILTER" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_GLB_FILTER::rec_}-->
<parameter name="rec_" type="std::uint8_t"/>
<code>\
(QP::QS::glbFilter_(static_cast&lt;std::int_fast16_t&gt;(rec_)))</code>
</operation>
<!--${QS-macros::QS_LOC_FILTER}-->
<operation name="QS_LOC_FILTER" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_LOC_FILTER::qsId_}-->
<parameter name="qsId_" type="std::uint8_t"/>
<code>\
(QP::QS::locFilter_(static_cast&lt;std::int_fast16_t&gt;(qsId_)))</code>
</operation>
<!--${QS-macros::QS_BEGIN_ID}-->
<operation name="QS_BEGIN_ID" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_BEGIN_ID::rec_}-->
<parameter name="rec_" type="std::uint8_t"/>
<!--${QS-macros::QS_BEGIN_ID::qsId_}-->
<parameter name="qsId_" type="std::uint8_t"/>
<code>\
if (QS_GLB_CHECK_(rec_) &amp;&amp; QS_LOC_CHECK_(qsId_)) { \
QS_CRIT_STAT \
QS_CRIT_ENTRY(); \
QS_MEM_SYS(); \
QP::QS::beginRec_(static_cast&lt;std::uint_fast8_t&gt;(rec_)); \
QS_TIME_PRE_(); {</code>
</operation>
<!--${QS-macros::QS_END}-->
<operation name="QS_END" type="void" visibility="0x03" properties="0x00">
<code>} \
QP::QS::endRec_(); \
QS_MEM_APP(); \
QS_CRIT_EXIT(); \
}</code>
</operation>
<!--${QS-macros::QS_FLUSH}-->
<operation name="QS_FLUSH" type="void" visibility="0x03" properties="0x00">
<code>(QP::QS::onFlush())</code>
</operation>
<!--${QS-macros::QS_BEGIN_INCRIT}-->
<operation name="QS_BEGIN_INCRIT" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_BEGIN_INCRIT::rec_}-->
<parameter name="rec_" type="std::uint8_t"/>
<!--${QS-macros::QS_BEGIN_INCRIT::qsId_}-->
<parameter name="qsId_" type="std::uint8_t"/>
<code>\
if (QS_GLB_CHECK_(rec_) &amp;&amp; QS_LOC_CHECK_(qsId_)) { \
QP::QS::beginRec_(rec_); \
QS_TIME_PRE_(); {</code>
</operation>
<!--${QS-macros::QS_END_INCRIT}-->
<operation name="QS_END_INCRIT" type="void" visibility="0x03" properties="0x00">
<code>} \
QP::QS::endRec_(); \
}</code>
</operation>
<!--${QS-macros::QS_GLB_CHECK_}-->
<operation name="QS_GLB_CHECK_" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_GLB_CHECK_::rec_}-->
<parameter name="rec_" type="std::uint8_t"/>
<code>\
((static_cast&lt;std::uint_fast8_t&gt;(QP::QS::filt_.glb[ \
static_cast&lt;std::uint_fast8_t&gt;(rec_) &gt;&gt; 3U]) \
&amp; (static_cast&lt;std::uint_fast8_t&gt;(1U) \
&lt;&lt; (static_cast&lt;std::uint_fast8_t&gt;(rec_) &amp; 7U))) != 0U)</code>
</operation>
<!--${QS-macros::QS_LOC_CHECK_}-->
<operation name="QS_LOC_CHECK_" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_LOC_CHECK_::qsId_}-->
<parameter name="qsId_" type="std::uint8_t"/>
<code>\
((static_cast&lt;std::uint_fast8_t&gt;(QP::QS::filt_.loc \
[static_cast&lt;std::uint_fast8_t&gt;(qsId_) &gt;&gt; 3U]) \
&amp; (static_cast&lt;std::uint_fast8_t&gt;(1U) \
&lt;&lt; (static_cast&lt;std::uint_fast8_t&gt;(qsId_) &amp; 7U))) != 0U)</code>
</operation>
<!--${QS-macros::QS_REC_DONE}-->
<operation name="QS_REC_DONE?ndef QS_REC_DONE" type="void" visibility="0x03" properties="0x00">
<code>(static_cast&lt;void&gt;(0))</code>
</operation>
<!--${QS-macros::QS_I8}-->
<operation name="QS_I8" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_I8::width_}-->
<parameter name="width_" type="std::uint8_t"/>
<!--${QS-macros::QS_I8::data_}-->
<parameter name="data_" type="std::int8_t"/>
<code>\
(QP::QS::u8_fmt_(static_cast&lt;std::uint8_t&gt;( \
(static_cast&lt;std::uint8_t&gt;(((width_) &lt;&lt; 4U) &amp; 0x7U)) \
| static_cast&lt;std::uint8_t&gt;(QP::QS::I8_ENUM_T)), (data_)))</code>
</operation>
<!--${QS-macros::QS_U8}-->
<operation name="QS_U8" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_U8::width_}-->
<parameter name="width_" type="std::uint8_t"/>
<!--${QS-macros::QS_U8::data_}-->
<parameter name="data_" type="std:u:int8_t"/>
<code>\
(QP::QS::u8_fmt_(static_cast&lt;std::uint8_t&gt;( \
(static_cast&lt;std::uint8_t&gt;((width_) &lt;&lt; 4U)) \
| static_cast&lt;std::uint8_t&gt;(QP::QS::U8_T)), (data_)))</code>
</operation>
<!--${QS-macros::QS_I16}-->
<operation name="QS_I16" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_I16::width_}-->
<parameter name="width_" type="std::uint8_t"/>
<!--${QS-macros::QS_I16::data_}-->
<parameter name="data_" type="std::int16_t"/>
<code>\
(QP::QS::u16_fmt_(static_cast&lt;std::uint8_t&gt;( \
(static_cast&lt;std::uint8_t&gt;((width_) &lt;&lt; 4U)) \
| static_cast&lt;std::uint8_t&gt;(QP::QS::I16_T)), (data_)))</code>
</operation>
<!--${QS-macros::QS_U16}-->
<operation name="QS_U16" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_U16::width_}-->
<parameter name="width_" type="std::uint8_t"/>
<!--${QS-macros::QS_U16::data_}-->
<parameter name="data_" type="std:u:int16_t"/>
<code>\
(QP::QS::u16_fmt_(static_cast&lt;std::uint8_t&gt;((((width_) &lt;&lt; 4U)) \
| static_cast&lt;std::uint8_t&gt;(QP::QS::U16_T)), (data_)))</code>
</operation>
<!--${QS-macros::QS_I32}-->
<operation name="QS_I32" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_I32::width_}-->
<parameter name="width_" type="std::uint8_t"/>
<!--${QS-macros::QS_I32::data_}-->
<parameter name="data_" type="std::int32_t"/>
<code>\
(QP::QS::u32_fmt_( \
static_cast&lt;std::uint8_t&gt;((static_cast&lt;std::uint8_t&gt;((width_) &lt;&lt; 4U)) \
| static_cast&lt;std::uint8_t&gt;(QP::QS::I32_T)), (data_)))</code>
</operation>
<!--${QS-macros::QS_U32}-->
<operation name="QS_U32" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_U32::width_}-->
<parameter name="width_" type="std::uint8_t"/>
<!--${QS-macros::QS_U32::data_}-->
<parameter name="data_" type="std:u:int32_t"/>
<code>\
(QP::QS::u32_fmt_(static_cast&lt;std::uint8_t&gt;( \
(static_cast&lt;std::uint8_t&gt;((width_) &lt;&lt; 4U)) \
| static_cast&lt;std::uint8_t&gt;(QP::QS::U32_T)), (data_)))</code>
</operation>
<!--${QS-macros::QS_I64}-->
<operation name="QS_I64" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_I64::width_}-->
<parameter name="width_" type="std::uint8_t"/>
<!--${QS-macros::QS_I64::data_}-->
<parameter name="data_" type="std::int64_t"/>
<code>\
(QP::QS::u64_fmt_(static_cast&lt;std::uint8_t&gt;( \
(static_cast&lt;std::uint8_t&gt;((width_) &lt;&lt; 4U)) \
| static_cast&lt;std::uint8_t&gt;(QP::QS::I64_T)), (data_)))</code>
</operation>
<!--${QS-macros::QS_U64}-->
<operation name="QS_U64" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_U64::width_}-->
<parameter name="width_" type="std::uint8_t"/>
<!--${QS-macros::QS_U64::data_}-->
<parameter name="data_" type="std:u:int64_t"/>
<code>\
(QP::QS::u64_fmt_(static_cast&lt;std::uint8_t&gt;( \
(static_cast&lt;std::uint8_t&gt;((width_) &lt;&lt; 4U)) \
| static_cast&lt;std::uint8_t&gt;(QP::QS::U64_T)), (data_)))</code>
</operation>
<!--${QS-macros::QS_F32}-->
<operation name="QS_F32" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_F32::width_}-->
<parameter name="width_" type="std::uint8_t"/>
<!--${QS-macros::QS_F32::data_}-->
<parameter name="data_" type="float32_t"/>
<code>\
(QP::QS::f32_fmt_(static_cast&lt;std::uint8_t&gt;( \
(static_cast&lt;std::uint8_t&gt;((width_) &lt;&lt; 4U)) \
| static_cast&lt;std::uint8_t&gt;(QP::QS::F32_T)), (data_)))</code>
</operation>
<!--${QS-macros::QS_F64}-->
<operation name="QS_F64" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_F64::width_}-->
<parameter name="width_" type="std::uint8_t"/>
<!--${QS-macros::QS_F64::data_}-->
<parameter name="data_" type="float64_t"/>
<code> \
(QP::QS::f64_fmt_(static_cast&lt;std::uint8_t&gt;( \
(static_cast&lt;std::uint8_t&gt;((width_) &lt;&lt; 4U)) \
| static_cast&lt;std::uint8_t&gt;(QP::QS::F64_T)), (data_)))</code>
</operation>
<!--${QS-macros::QS_STR}-->
<operation name="QS_STR" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_STR::str_}-->
<parameter name="str_" type="char const *"/>
<code>(QP::QS::str_fmt_(str_))</code>
</operation>
<!--${QS-macros::QS_MEM}-->
<operation name="QS_MEM" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_MEM::mem_}-->
<parameter name="mem_" type="void *"/>
<!--${QS-macros::QS_MEM::size_}-->
<parameter name="size_" type="std:u:int8_t"/>
<code>(QP::QS::mem_fmt_((mem_), (size_)))</code>
</operation>
<!--${QS-macros::QS_ENUM}-->
<operation name="QS_ENUM" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_ENUM::group_}-->
<parameter name="group_" type="std::uint8_t const"/>
<!--${QS-macros::QS_ENUM::value_}-->
<parameter name="value_" type="enum_t const"/>
<code>\
(QP::QS::u8_fmt_(static_cast&lt;std::uint8_t&gt;(0x80U | ((group_) &lt;&lt; 4U)) \
| static_cast&lt;std::uint8_t&gt;(QP::QS::I8_ENUM_T),\
static_cast&lt;std::uint8_t&gt;(value_)))</code>
</operation>
<!--${QS-macros::QS_TIME_PRE_}-->
<operation name="QS_TIME_PRE_? (QS_TIME_SIZE == 2U)" type="void" visibility="0x03" properties="0x00">
<code>(QP::QS::u16_raw_(QP::QS::onGetTime()))</code>
</operation>
<!--${QS-macros::QS_TIME_PRE_}-->
<operation name="QS_TIME_PRE_? (QS_TIME_SIZE == 4U)" type="void" visibility="0x03" properties="0x00">
<code>(QP::QS::u32_raw_(QP::QS::onGetTime()))</code>
</operation>
<!--${QS-macros::QS_OBJ}-->
<operation name="QS_OBJ? (QS_OBJ_PTR_SIZE == 2U)" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_OBJ::obj_}-->
<parameter name="obj_" type="void const *"/>
<code>(QP::QS::u16_fmt_(QP::QS::OBJ_T, \
reinterpret_cast&lt;std::uint16_t&gt;(obj_)))</code>
</operation>
<!--${QS-macros::QS_OBJ}-->
<operation name="QS_OBJ? (QS_OBJ_PTR_SIZE == 4U)" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_OBJ::obj_}-->
<parameter name="obj_" type="void const *"/>
<code>(QP::QS::u32_fmt_(QP::QS::OBJ_T, \
reinterpret_cast&lt;std::uint32_t&gt;(obj_)))</code>
</operation>
<!--${QS-macros::QS_OBJ}-->
<operation name="QS_OBJ? (QS_OBJ_PTR_SIZE == 8U)" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_OBJ::obj_}-->
<parameter name="obj_" type="void const *"/>
<code>(QP::QS::u64_fmt_(QP::QS::OBJ_T, \
reinterpret_cast&lt;std::uint64_t&gt;(obj_)))</code>
</operation>
<!--${QS-macros::QS_FUN}-->
<operation name="QS_FUN? (QS_FUN_PTR_SIZE == 2U)" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_FUN::fun_}-->
<parameter name="fun_" type="QSpyFunPtr"/>
<code>(QP::QS::u16_fmt_(QP::QS::FUN_T, \
reinterpret_cast&lt;std::uint16_t&gt;(fun_)))</code>
</operation>
<!--${QS-macros::QS_FUN}-->
<operation name="QS_FUN? (QS_FUN_PTR_SIZE == 4U)" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_FUN::fun_}-->
<parameter name="fun_" type="QSpyFunPtr"/>
<code>(QP::QS::u32_fmt_(QP::QS::FUN_T, \
reinterpret_cast&lt;std::uint32_t&gt;(fun_)))</code>
</operation>
<!--${QS-macros::QS_FUN}-->
<operation name="QS_FUN? (QS_FUN_PTR_SIZE == 8U)" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_FUN::fun_}-->
<parameter name="fun_" type="QSpyFunPtr"/>
<code>(QP::QS::u64_fmt_(QP::QS::FUN_T, \
reinterpret_cast&lt;std::uint64_t&gt;(fun_)))</code>
</operation>
<!--${QS-macros::QS_SIG}-->
<operation name="QS_SIG? (Q_SIGNAL_SIZE == 1U)" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_SIG::sig_}-->
<parameter name="sig_" type="QP::QSignal"/>
<!--${QS-macros::QS_SIG::obj_}-->
<parameter name="obj_" type="void const *"/>
<code>\
QP::QS::u8_fmt_(QP::QS::SIG_T, static_cast&lt;std::uint8_t&gt;(sig_)); \
QP::QS::obj_raw_(obj_)</code>
</operation>
<!--${QS-macros::QS_SIG}-->
<operation name="QS_SIG? (Q_SIGNAL_SIZE == 2U)" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_SIG::sig_}-->
<parameter name="sig_" type="QP::QSignal"/>
<!--${QS-macros::QS_SIG::obj_}-->
<parameter name="obj_" type="void const *"/>
<code>\
QP::QS::u16_fmt_(QP::QS::SIG_T, static_cast&lt;std::uint16_t&gt;(sig_)); \
QP::QS::obj_raw_(obj_)</code>
</operation>
<!--${QS-macros::QS_SIG}-->
<operation name="QS_SIG? (Q_SIGNAL_SIZE == 4U)" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_SIG::sig_}-->
<parameter name="sig_" type="QP::QSignal"/>
<!--${QS-macros::QS_SIG::obj_}-->
<parameter name="obj_" type="void const *"/>
<code>\
QP::QS::u32_fmt_(QP::QS::SIG_T, static_cast&lt;std::uint32_t&gt;(sig_)); \
QP::QS::obj_raw_(obj_)</code>
</operation>
<!--${QS-macros::QS_SIG_DICTIONARY}-->
<operation name="QS_SIG_DICTIONARY" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_SIG_DICTIONAR~::sig_}-->
<parameter name="sig_" type="QP::QSignal"/>
<!--${QS-macros::QS_SIG_DICTIONAR~::obj_}-->
<parameter name="obj_" type="void const *"/>
<code>\
(QP::QS::sig_dict_pre_((sig_), (obj_), #sig_))</code>
</operation>
<!--${QS-macros::QS_OBJ_DICTIONARY}-->
<operation name="QS_OBJ_DICTIONARY" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_OBJ_DICTIONAR~::obj_}-->
<parameter name="obj_" type="void const *"/>
<code>\
(QP::QS::obj_dict_pre_((obj_), #obj_))</code>
</operation>
<!--${QS-macros::QS_OBJ_ARR_DICTIONARY}-->
<operation name="QS_OBJ_ARR_DICTIONARY" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_OBJ_ARR_DICTI~::obj_}-->
<parameter name="obj_" type="void const *"/>
<!--${QS-macros::QS_OBJ_ARR_DICTI~::idx_}-->
<parameter name="idx_" type="unsigned"/>
<code>\
(QP::QS::obj_arr_dict_pre_((obj_), (idx_), #obj_))</code>
</operation>
<!--${QS-macros::QS_FUN_DICTIONARY}-->
<operation name="QS_FUN_DICTIONARY" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_FUN_DICTIONAR~::fun_}-->
<parameter name="fun_" type="QSpyFunPtr"/>
<code>\
(QP::QS::fun_dict_pre_( \
QP::QS::force_cast&lt;void (*)()&gt;(fun_), #fun_))</code>
</operation>
<!--${QS-macros::QS_USR_DICTIONARY}-->
<operation name="QS_USR_DICTIONARY" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_USR_DICTIONAR~::rec_}-->
<parameter name="rec_" type="std::unit8_t"/>
<code>\
(QP::QS::usr_dict_pre_((rec_), #rec_))</code>
</operation>
<!--${QS-macros::QS_ENUM_DICTIONARY}-->
<operation name="QS_ENUM_DICTIONARY" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_ENUM_DICTIONA~::value_}-->
<parameter name="value_" type="enum_t const"/>
<!--${QS-macros::QS_ENUM_DICTIONA~::group_}-->
<parameter name="group_" type="std::uint8_t const"/>
<code>\
(QP::QS::enum_dict_pre_((value_), (group_), #value_))</code>
</operation>
<!--${QS-macros::QS_QF_CRIT_ENTRY}-->
<operation name="QS_QF_CRIT_ENTRY" type="void" visibility="0x03" properties="0x00">
<code>(QP::QS::crit_entry_pre_())</code>
</operation>
<!--${QS-macros::QS_QF_CRIT_EXIT}-->
<operation name="QS_QF_CRIT_EXIT" type="void" visibility="0x03" properties="0x00">
<code>(QP::QS::crit_exit_pre_())</code>
</operation>
<!--${QS-macros::QS_QF_ISR_ENTRY}-->
<operation name="QS_QF_ISR_ENTRY" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_QF_ISR_ENTRY::isrnest_}-->
<parameter name="isrnest_" type="std::uint_fast8_t"/>
<!--${QS-macros::QS_QF_ISR_ENTRY::prio_}-->
<parameter name="prio_" type="std::uint_fast8_t"/>
<code>\
(QP::QS::isr_entry_pre_((isrnest_), (prio_)))</code>
</operation>
<!--${QS-macros::QS_QF_ISR_EXIT}-->
<operation name="QS_QF_ISR_EXIT" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_QF_ISR_EXIT::isrnest_}-->
<parameter name="isrnest_" type="std::uint_fast8_t"/>
<!--${QS-macros::QS_QF_ISR_EXIT::prio_}-->
<parameter name="prio_" type="std::uint_fast8_t"/>
<code>\
(QP::QS::isr_exit_pre_((isrnest_), (prio_)))</code>
</operation>
<!--${QS-macros::QS_ONLY}-->
<operation name="QS_ONLY" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_ONLY::code_}-->
<parameter name="code_" type="&lt;code&gt;"/>
<code>(code_)</code>
</operation>
<!--${QS-macros::QS_ASSERTION}-->
<operation name="QS_ASSERTION" type="void" visibility="0x03" properties="0x00">
<!--${QS-macros::QS_ASSERTION::module_}-->
<parameter name="module_" type="char const *"/>
<!--${QS-macros::QS_ASSERTION::id_}-->
<parameter name="id_" type="int_t"/>
<!--${QS-macros::QS_ASSERTION::delay_}-->
<parameter name="delay_" type="unsigned"/>
<code>\
(QP::QS::assertion_pre_((module_), (id_), (delay_)))</code>
</operation>
<!--${QS-macros::QS_EOD}-->
<attribute name="QS_EOD" type="std::uint16_t" visibility="0x03" properties="0x00">
<code>(static_cast&lt;std::uint16_t&gt;(0xFFFFU))</code>
</attribute>
<!--${QS-macros::QS_CMD}-->
<attribute name="QS_CMD" type="std::uint8_t" visibility="0x03" properties="0x00">
<code>(static_cast&lt;std::uint8_t&gt;(7U))</code>
</attribute>
<!--${QS-macros::QS_HEX_FMT}-->
<attribute name="QS_HEX_FMT" type="std::uint8_t" visibility="0x03" properties="0x00">
<code>(static_cast&lt;std::uint8_t&gt;(0x0FU))</code>
</attribute>
<!--${QS-macros::QS_CRIT_STAT}-->
<attribute name="QS_CRIT_STAT?ndef QS_CRIT_STAT" type="" visibility="0x03" properties="0x00">
<code>QF_CRIT_STAT</code>
</attribute>
<!--${QS-macros::QS_CRIT_ENTRY}-->
<operation name="QS_CRIT_ENTRY?ndef QS_CRIT_ENTRY" type="void" visibility="0x03" properties="0x00">
<code>QF_CRIT_ENTRY()</code>
</operation>
<!--${QS-macros::QS_CRIT_EXIT}-->
<operation name="QS_CRIT_EXIT?ndef QS_CRIT_EXIT" type="void" visibility="0x03" properties="0x00">
<code>QF_CRIT_EXIT()</code>
</operation>
<!--${QS-macros::QS_MEM_SYS}-->
<operation name="QS_MEM_SYS?ndef QS_MEM_SYS" type="void" visibility="0x03" properties="0x00">
<code>QF_MEM_SYS()</code>
</operation>
<!--${QS-macros::QS_MEM_APP}-->
<operation name="QS_MEM_APP?ndef QS_MEM_APP" type="void" visibility="0x03" properties="0x00">
<code>QF_MEM_APP()</code>
</operation>
</package>
<!--${include}-->
<directory name="include">
<!--${include::qp.hpp}-->
<file name="qp.hpp">
<text>#ifndef QP_HPP_
#define QP_HPP_
//============================================================================
#define QP_VERSION_STR &quot;7.3.5-rc.1&quot;
#define QP_VERSION 735U
#define QP_RELEASE 0x70A1DEF0U
//============================================================================
//! @cond INTERNAL
#ifndef Q_SIGNAL_SIZE
#define Q_SIGNAL_SIZE 2U
#endif // ndef Q_SIGNAL_SIZE
#ifndef QF_MAX_ACTIVE
#define QF_MAX_ACTIVE 32U
#endif
#if (QF_MAX_ACTIVE &gt; 64U)
#error QF_MAX_ACTIVE exceeds the maximum of 64U;
#endif
#ifndef QF_MAX_TICK_RATE
#define QF_MAX_TICK_RATE 1U
#endif
#if (QF_MAX_TICK_RATE &gt; 15U)
#error QF_MAX_TICK_RATE exceeds the maximum of 15U;
#endif
#ifndef QF_MAX_EPOOL
#define QF_MAX_EPOOL 3U
#endif
#if (QF_MAX_EPOOL &gt; 15U)
#error QF_MAX_EPOOL exceeds the maximum of 15U;
#endif
#ifndef QF_TIMEEVT_CTR_SIZE
#define QF_TIMEEVT_CTR_SIZE 4U
#endif
#if (QF_TIMEEVT_CTR_SIZE &gt; 4U)
#error QF_TIMEEVT_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U;
#endif
#ifndef QF_EVENT_SIZ_SIZE
#define QF_EVENT_SIZ_SIZE 2U
#endif
#if (QF_EVENT_SIZ_SIZE &gt; 4U)
#error QF_EVENT_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U;
#endif
//! @endcond
//============================================================================
$declare ${glob-types}
$declare ${QEP}
$declare ${QEP-macros}
$declare ${QF::types}
$declare ${QF::QActive}
$declare ${QF::QMActive}
$declare ${QF::QTimeEvt}
$declare ${QF::QTicker}
$declare ${QF::QF-base}
$declare ${QF::QF-dyn}
extern &quot;C&quot; {
$declare ${QF-extern-C}
} // extern &quot;C&quot;
$declare ${QF-macros}
#endif // QP_HPP_</text>
</file>
<!--${include::qp_pkg.hpp}-->
<file name="qp_pkg.hpp">
<text>#ifndef QP_PKG_HPP_
#define QP_PKG_HPP_
$declare ${QF::QF-pkg}
#define QF_CONST_CAST_(type_, ptr_) const_cast&lt;type_&gt;(ptr_)
#define QF_PTR_RANGE_(x_, min_, max_) (((min_) &lt;= (x_)) &amp;&amp; ((x_) &lt;= (max_)))
#define Q_UINTPTR_CAST_(ptr_) (reinterpret_cast&lt;std::uintptr_t&gt;(ptr_))
#define Q_ACTION_CAST(act_) (reinterpret_cast&lt;QP::QActionHandler&gt;(act_))
namespace QP {
// Bitmasks are for the QTimeEvt::refCtr_ attribute (inherited from QEvt).
// In QTimeEvt this attribute is NOT used for reference counting.
constexpr std::uint8_t TE_IS_LINKED = 1U &lt;&lt; 7U; // flag
constexpr std::uint8_t TE_WAS_DISARMED = 1U &lt;&lt; 6U; // flag
constexpr std::uint8_t TE_TICK_RATE = 0x0FU; // bitmask
inline void QEvt_refCtr_inc_(QEvt const * const e) noexcept {
(QF_CONST_CAST_(QEvt*, e))-&gt;refCtr_ = e-&gt;refCtr_ + 1U;
}
inline void QEvt_refCtr_dec_(QEvt const * const e) noexcept {
(QF_CONST_CAST_(QEvt*, e))-&gt;refCtr_ = e-&gt;refCtr_ - 1U;
}
} // namespace QP
#endif // QP_PKG_HPP_</text>
</file>
<!--${include::qequeue.hpp}-->
<file name="qequeue.hpp">
<text>#ifndef QEQUEUE_HPP_
#define QEQUEUE_HPP_
#ifndef QF_EQUEUE_CTR_SIZE
#define QF_EQUEUE_CTR_SIZE 1U
#endif
namespace QP {
#if (QF_EQUEUE_CTR_SIZE == 1U)
using QEQueueCtr = std::uint8_t;
#elif (QF_EQUEUE_CTR_SIZE == 2U)
using QEQueueCtr = std::uint16_t;
#elif (QF_EQUEUE_CTR_SIZE == 4U)
using QEQueueCtr = std::uint32_t;
#else
#error &quot;QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U&quot;
#endif
class QEvt; // forward declaration
} // namespace QP
$declare ${QF::QEQueue}
#endif // QEQUEUE_HPP_</text>
</file>
<!--${include::qmpool.hpp}-->
<file name="qmpool.hpp">
<text>#ifndef QMPOOL_HPP_
#define QMPOOL_HPP_
#ifndef QF_MPOOL_SIZ_SIZE
#define QF_MPOOL_SIZ_SIZE 2U
#endif
#ifndef QF_MPOOL_CTR_SIZE
#define QF_MPOOL_CTR_SIZE 2U
#endif
namespace QP {
#if (QF_MPOOL_SIZ_SIZE == 1U)
using QMPoolSize = std::uint8_t;
#elif (QF_MPOOL_SIZ_SIZE == 2U)
using QMPoolSize = std::uint16_t;
#elif (QF_MPOOL_SIZ_SIZE == 4U)
using QMPoolSize = std::uint32_t;
#else
#error &quot;QF_MPOOL_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U&quot;
#endif
#if (QF_MPOOL_CTR_SIZE == 1U)
using QMPoolCtr = std::uint8_t;
#elif (QF_MPOOL_CTR_SIZE == 2U)
using QMPoolCtr = std::uint16_t;
#elif (QF_MPOOL_CTR_SIZE == 4U)
using QMPoolCtr = std::uint32_t;
#else
#error &quot;QF_MPOOL_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U&quot;
#endif
} // namespace QP
#define QF_MPOOL_EL(evType_) struct { \
QP::QFreeBlock sto_[((sizeof(evType_) - 1U) \
/ sizeof(QP::QFreeBlock)) + 1U]; }
$declare ${QF::QFreeBlock}
$declare ${QF::QMPool}
#endif // QMPOOL_HPP_</text>
</file>
<!--${include::qv.hpp}-->
<file name="qv.hpp">
<text>#ifndef QV_HPP_
#define QV_HPP_
$declare ${QV::QV-base}
//============================================================================
// interface used only for internal implementation, but not in applications
#ifdef QP_IMPL
$declare ${QV-impl}
$declare ${QF_EPOOL-impl}
#endif // QP_IMPL
#endif // QV_HPP_</text>
</file>
<!--${include::qk.hpp}-->
<file name="qk.hpp">
<text>#ifndef QK_HPP_
#define QK_HPP_
$declare ${QK::QSchedStatus}
$declare ${QK::QK-base}
extern &quot;C&quot; {
$declare ${QK-extern-C}
} // extern &quot;C&quot;
//============================================================================
// interface used only for internal implementation, but not in applications
#ifdef QP_IMPL
$declare ${QK-impl}
$declare ${QF_EPOOL-impl}
#endif // QP_IMPL
#endif // QK_HPP_</text>
</file>
<!--${include::qxk.hpp}-->
<file name="qxk.hpp">
<text>#ifndef QXK_HPP_
#define QXK_HPP_
$declare ${QXK::QSchedStatus}
$declare ${QXK::QXTHREAD_NO_TIMEOUT}
$declare ${QXK::QXK-base}
$declare ${QXK::QXThread}
$declare ${QXK::QXSemaphore}
$declare ${QXK::QXMutex}
extern &quot;C&quot; {
$declare ${QXK-extern-C}
} // extern &quot;C&quot;
//============================================================================
// interface used only for internal implementation, but not in applications
#ifdef QP_IMPL
$declare ${QXK-impl}
$declare ${QF_EPOOL-impl}
namespace QP {
namespace QXK {
enum TimeoutSigs : QSignal {
DELAY_SIG = 1U,
TIMEOUT_SIG
};
} // namespace QXK
} // namespace QP
#endif // QP_IMPL
#endif // QXK_HPP_</text>
</file>
<!--${include::qs.hpp}-->
<file name="qs.hpp">
<text>#ifndef QS_HPP_
#define QS_HPP_
#ifndef Q_SPY
#error &quot;Q_SPY must be defined to include qs.hpp&quot;
#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}
$declare ${QS::filters}
$declare ${QS-macros}
//============================================================================
//! @cond INTERNAL
namespace QP {
namespace QS {
struct Attr {
void const * locFilter_AP; //!&lt; @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}
//============================================================================
#ifdef Q_UTEST
$declare ${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}
$declare ${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&lt;void (*)()&gt;(fun_));
#define QS_TEST_PROBE(code_) \
if (qs_tp_ != 0U) { code_ }
#define QS_TEST_PROBE_ID(id_, code_) \
if (qs_tp_ == static_cast&lt;std::uint32_t&gt;(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&lt;void&gt;(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}
#endif // QS_HPP_</text>
</file>
<!--${include::qs_dummy.hpp}-->
<file name="qs_dummy.hpp">
<text>#ifndef QS_DUMMY_HPP_
#define QS_DUMMY_HPP_
#ifdef Q_SPY
#error &quot;Q_SPY must NOT be defined to include qs_dummy.hpp&quot;
#endif
#define QS_INIT(arg_) (true)
#define QS_EXIT() static_cast&lt;void&gt;(0)
#define QS_DUMP() static_cast&lt;void&gt;(0)
#define QS_GLB_FILTER(rec_) static_cast&lt;void&gt;(0)
#define QS_LOC_FILTER(qsId_) static_cast&lt;void&gt;(0)
#define QS_GET_BYTE(pByte_) (0xFFFFU)
#define QS_GET_BLOCK(pSize_) (nullptr)
#define QS_BEGIN_ID(rec_, qsId_) if (false) {
#define QS_END() }
#define QS_BEGIN_INCRIT(rec_, qsId_) if (false) {
#define QS_END_INCRIT() }
#define QS_I8(width_, data_) static_cast&lt;void&gt;(0)
#define QS_U8(width_, data_) static_cast&lt;void&gt;(0)
#define QS_I16(width_, data_) static_cast&lt;void&gt;(0)
#define QS_U16(width_, data_) static_cast&lt;void&gt;(0)
#define QS_I32(width_, data_) static_cast&lt;void&gt;(0)
#define QS_U32(width_, data_) static_cast&lt;void&gt;(0)
#define QS_F32(width_, data_) static_cast&lt;void&gt;(0)
#define QS_F64(width_, data_) static_cast&lt;void&gt;(0)
#define QS_I64(width_, data_) static_cast&lt;void&gt;(0)
#define QS_U64(width_, data_) static_cast&lt;void&gt;(0)
#define QS_ENUM(group_, value_) static_cast&lt;void&gt;(0)
#define QS_STR(str_) static_cast&lt;void&gt;(0)
#define QS_MEM(mem_, size_) static_cast&lt;void&gt;(0)
#define QS_SIG(sig_, obj_) static_cast&lt;void&gt;(0)
#define QS_OBJ(obj_) static_cast&lt;void&gt;(0)
#define QS_FUN(fun_) static_cast&lt;void&gt;(0)
#define QS_SIG_DICTIONARY(sig_, obj_) static_cast&lt;void&gt;(0)
#define QS_OBJ_DICTIONARY(obj_) static_cast&lt;void&gt;(0)
#define QS_OBJ_ARR_DICTIONARY(obj_, idx_) static_cast&lt;void&gt;(0)
#define QS_FUN_DICTIONARY(fun_) static_cast&lt;void&gt;(0)
#define QS_USR_DICTIONARY(rec_) static_cast&lt;void&gt;(0)
#define QS_ENUM_DICTIONARY(value_, group_) static_cast&lt;void&gt;(0)
#define QS_ASSERTION(module_, loc_, delay_) static_cast&lt;void&gt;(0)
#define QS_FLUSH() static_cast&lt;void&gt;(0)
#define QS_TEST_PROBE_DEF(fun_)
#define QS_TEST_PROBE(code_)
#define QS_TEST_PROBE_ID(id_, code_)
#define QS_TEST_PAUSE() static_cast&lt;void&gt;(0)
#define QS_OUTPUT() static_cast&lt;void&gt;(0)
#define QS_RX_INPUT() static_cast&lt;void&gt;(0)
#define QS_ONLY(code_) static_cast&lt;void&gt;(0)
//============================================================================
// interface used only for internal implementation, but not in applications
#ifdef QP_IMPL
// predefined QS trace records
#define QS_BEGIN_PRE_(rec_, qsId_) if (false) {
#define QS_END_PRE_() }
#define QS_BEGIN_PRE_(rec_, qsId_) if (false) {
#define QS_END_PRE_() }
#define QS_U8_PRE_(data_) static_cast&lt;void&gt;(0)
#define QS_2U8_PRE_(data1_, data2_) static_cast&lt;void&gt;(0)
#define QS_U16_PRE_(data_) static_cast&lt;void&gt;(0)
#define QS_U32_PRE_(data_) static_cast&lt;void&gt;(0)
#define QS_TIME_PRE_() static_cast&lt;void&gt;(0)
#define QS_SIG_PRE_(sig_) static_cast&lt;void&gt;(0)
#define QS_EVS_PRE_(size_) static_cast&lt;void&gt;(0)
#define QS_OBJ_PRE_(obj_) static_cast&lt;void&gt;(0)
#define QS_FUN_PRE_(fun_) static_cast&lt;void&gt;(0)
#define QS_EQC_PRE_(ctr_) static_cast&lt;void&gt;(0)
#define QS_MPC_PRE_(ctr_) static_cast&lt;void&gt;(0)
#define QS_MPS_PRE_(size_) static_cast&lt;void&gt;(0)
#define QS_TEC_PRE_(ctr_) static_cast&lt;void&gt;(0)
#define QS_CRIT_STAT
#define QS_CRIT_ENTRY() static_cast&lt;void&gt;(0)
#define QS_CRIT_EXIT() static_cast&lt;void&gt;(0)
#define QS_MEM_SYS() static_cast&lt;void&gt;(0)
#define QS_MEM_APP() static_cast&lt;void&gt;(0)
#define QS_TR_CRIT_ENTRY() static_cast&lt;void&gt;(0)
#define QS_TR_CRIT_EXIT() static_cast&lt;void&gt;(0)
#define QS_TR_ISR_ENTRY(isrnest_, prio_) static_cast&lt;void&gt;(0)
#define QS_Tr_ISR_EXIT(isrnest_, prio_) static_cast&lt;void&gt;(0)
#endif // QP_IMPL
#endif // QS_DUMMY_HPP_</text>
</file>
<!--${include::qs_pkg.hpp}-->
<file name="qs_pkg.hpp">
<text>#ifndef QS_PKG_HPP_
#define QS_PKG_HPP_
//============================================================================
//! @cond INTERNAL
namespace QP {
//! QS received record types (RX channel)
enum QSpyRxRecords : std::uint8_t {
QS_RX_INFO, //!&lt; query Target info (ver, config, tstamp)
QS_RX_COMMAND, //!&lt; execute a user-defined command in the Target
QS_RX_RESET, //!&lt; reset the Target
QS_RX_TICK, //!&lt; call system clock tick in the Target
QS_RX_PEEK, //!&lt; peek Target memory
QS_RX_POKE, //!&lt; poke Target memory
QS_RX_FILL, //!&lt; fill Target memory
QS_RX_TEST_SETUP, //!&lt; test setup
QS_RX_TEST_TEARDOWN, //!&lt; test teardown
QS_RX_TEST_PROBE, //!&lt; set a Test-Probe in the Target
QS_RX_GLB_FILTER, //!&lt; set global filters in the Target
QS_RX_LOC_FILTER, //!&lt; set local filters in the Target
QS_RX_AO_FILTER, //!&lt; set local AO filter in the Target
QS_RX_CURR_OBJ, //!&lt; set the &quot;current-object&quot; in the Target
QS_RX_TEST_CONTINUE, //!&lt; continue a test after QS_TEST_PAUSE()
QS_RX_QUERY_CURR, //!&lt; query the &quot;current object&quot; in the Target
QS_RX_EVENT //!&lt; inject an event to the Target
};
constexpr std::uint8_t QS_FRAME {0x7EU};
constexpr std::uint8_t QS_ESC {0x7DU};
constexpr std::uint8_t QS_ESC_XOR {0x20U};
constexpr std::uint8_t QS_GOOD_CHKSUM {0xFFU};
} // namespace QP
//----------------------------------------------------------------------------
#define QS_BEGIN_PRE_(rec_, qsId_) \
if (QS_GLB_CHECK_(rec_) &amp;&amp; QS_LOC_CHECK_(qsId_)) { \
QP::QS::beginRec_(static_cast&lt;std::uint_fast8_t&gt;(rec_));
#define QS_END_PRE_() QP::QS::endRec_(); }
#define QS_U8_PRE_(data_) \
(QP::QS::u8_raw_(static_cast&lt;std::uint8_t&gt;(data_)))
#define QS_2U8_PRE_(data1_, data2_) \
(QP::QS::u8u8_raw_(static_cast&lt;std::uint8_t&gt;(data1_), \
static_cast&lt;std::uint8_t&gt;(data2_)))
#define QS_U16_PRE_(data_) \
(QP::QS::u16_raw_(static_cast&lt;std::uint16_t&gt;(data_)))
#define QS_U32_PRE_(data_) \
(QP::QS::u32_raw_(static_cast&lt;std::uint32_t&gt;(data_)))
#define QS_STR_PRE_(msg_) (QP::QS::str_raw_(msg_))
#define QS_OBJ_PRE_(obj_) (QP::QS::obj_raw_(obj_))
#if (!defined Q_SIGNAL_SIZE || (Q_SIGNAL_SIZE == 1U))
#define QS_SIG_PRE_(sig_) \
(QP::QS::u8_raw_(static_cast&lt;std::uint8_t&gt;(sig_)))
#elif (Q_SIGNAL_SIZE == 2U)
#define QS_SIG_PRE_(sig_) \
(QP::QS::u16_raw_(static_cast&lt;std::uint16_t&gt;(sig_)))
#elif (Q_SIGNAL_SIZE == 4U)
#define QS_SIG_PRE_(sig_) \
(QP::QS::u32_raw_(static_cast&lt;std::uint32_t&gt;(sig_)))
#endif
#if (!defined QS_FUN_PTR_SIZE || (QS_FUN_PTR_SIZE == 2U))
#define QS_FUN_PRE_(fun_) \
(QP::QS::u16_raw_(reinterpret_cast&lt;std::uint16_t&gt;(fun_)))
#elif (QS_FUN_PTR_SIZE == 4U)
#define QS_FUN_PRE_(fun_) \
(QP::QS::u32_raw_(reinterpret_cast&lt;std::uint32_t&gt;(fun_)))
#elif (QS_FUN_PTR_SIZE == 8U)
#define QS_FUN_PRE_(fun_) \
(QP::QS::u64_raw_(reinterpret_cast&lt;std::uint64_t&gt;(fun_)))
#else
#define QS_FUN_PRE_(fun_) \
(QP::QS::u32_raw_(reinterpret_cast&lt;std::uint32_t&gt;(fun_)))
#endif
//----------------------------------------------------------------------------
#if (!defined QF_EQUEUE_CTR_SIZE || (QF_EQUEUE_CTR_SIZE == 1U))
#define QS_EQC_PRE_(ctr_) \
QP::QS::u8_raw_(static_cast&lt;std::uint8_t&gt;(ctr_))
#elif (QF_EQUEUE_CTR_SIZE == 2U)
#define QS_EQC_PRE_(ctr_) \
QP::QS::u16_raw_(static_cast&lt;std::uint16_t&gt;(ctr_))
#elif (QF_EQUEUE_CTR_SIZE == 4U)
#define QS_EQC_PRE_(ctr_) \
QP::QS::u32_raw_(static_cast&lt;std::uint32_t&gt;(ctr_))
#else
#error &quot;QF_EQUEUE_CTR_SIZE not defined&quot;
#endif
#if (!defined QF_EVENT_SIZ_SIZE || (QF_EVENT_SIZ_SIZE == 1U))
#define QS_EVS_PRE_(size_) \
QP::QS::u8_raw_(static_cast&lt;std::uint8_t&gt;(size_))
#elif (QF_EVENT_SIZ_SIZE == 2U)
#define QS_EVS_PRE_(size_) \
QP::QS::u16_raw_(static_cast&lt;std::uint16_t&gt;(size_))
#elif (QF_EVENT_SIZ_SIZE == 4U)
#define QS_EVS_PRE_(size_) \
QP::QS::u32_raw_(static_cast&lt;std::uint32_t&gt;(size_))
#endif
#if (!defined QF_MPOOL_SIZ_SIZE || (QF_MPOOL_SIZ_SIZE == 1U))
#define QS_MPS_PRE_(size_) \
QP::QS::u8_raw_(static_cast&lt;std::uint8_t&gt;(size_))
#elif (QF_MPOOL_SIZ_SIZE == 2U)
#define QS_MPS_PRE_(size_) \
QP::QS::u16_raw_(static_cast&lt;std::uint16_t&gt;(size_))
#elif (QF_MPOOL_SIZ_SIZE == 4U)
#define QS_MPS_PRE_(size_) \
QP::QS::u32_raw_(static_cast&lt;std::uint32_t&gt;(size_))
#endif
#if (!defined QF_MPOOL_CTR_SIZE || (QF_MPOOL_CTR_SIZE == 1U))
#define QS_MPC_PRE_(ctr_) \
QP::QS::u8_raw_(static_cast&lt;std::uint8_t&gt;(ctr_))
#elif (QF_MPOOL_CTR_SIZE == 2U)
#define QS_MPC_PRE_(ctr_) \
QP::QS::u16_raw_(static_cast&lt;std::uint16_t&gt;(ctr_))
#elif (QF_MPOOL_CTR_SIZE == 4U)
#define QS_MPC_PRE_(ctr_) \
QP::QS::u32_raw_(static_cast&lt;std::uint32_t&gt;(ctr_))
#endif
#if (!defined QF_TIMEEVT_CTR_SIZE || (QF_TIMEEVT_CTR_SIZE == 1U))
#define QS_TEC_PRE_(ctr_) \
QP::QS::u8_raw_(static_cast&lt;std::uint8_t&gt;(ctr_))
#elif (QF_TIMEEVT_CTR_SIZE == 2U)
#define QS_TEC_PRE_(ctr_) \
QP::QS::u16_raw_(static_cast&lt;std::uint16_t&gt;(ctr_))
#elif (QF_TIMEEVT_CTR_SIZE == 4U)
#define QS_TEC_PRE_(ctr_) \
QP::QS::u32_raw_(static_cast&lt;std::uint32_t&gt;(ctr_))
#endif
#define QS_REC_NUM_(enum_) (static_cast&lt;std::uint_fast8_t&gt;(enum_))
//----------------------------------------------------------------------------
#define QS_INSERT_BYTE_(b_) \
buf[head] = (b_); \
++head; \
if (head == end) { \
head = 0U; \
}
#define QS_INSERT_ESC_BYTE_(b_) \
chksum = static_cast&lt;std::uint8_t&gt;(chksum + (b_)); \
if (((b_) != QS_FRAME) &amp;&amp; ((b_) != QS_ESC)) { \
QS_INSERT_BYTE_(b_) \
} \
else { \
QS_INSERT_BYTE_(QS_ESC) \
QS_INSERT_BYTE_(static_cast&lt;std::uint8_t&gt;((b_) ^ QS_ESC_XOR)) \
priv_.used = priv_.used + 1U; \
}
//----------------------------------------------------------------------------
#if (defined Q_UTEST) &amp;&amp; (Q_UTEST != 0)
namespace QP {
namespace QS {
void processTestEvts_();
} // namespace QS
} // namespace QP
#endif // Q_UTEST != 0
//! @endcond
//============================================================================
#endif // QS_PKG_HPP_</text>
</file>
<!--${include::qstamp.hpp}-->
<file name="qstamp.hpp">
<text>#ifndef QSTAMP_HPP_
#define QSTAMP_HPP_
namespace QP {
extern char const BUILD_DATE[12];
extern char const BUILD_TIME[9];
} // namespace QP
#endif // QSTAMP_HPP_</text>
</file>
<!--${include::qpcpp.hpp}-->
<file name="qpcpp.hpp">
<text>#ifndef QPCPP_HPP_
#define QPCPP_HPP_
//============================================================================
#include &quot;qp_port.hpp&quot; // QP port from the port directory
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS/C++ port from the port directory
#else
#include &quot;qs_dummy.hpp&quot; // QS/C++ dummy (inactive) interface
#endif
//============================================================================
#ifndef QP_API_VERSION
#define QP_API_VERSION 0
#endif // QP_API_VERSION
//============================================================================
// QP/C++ API compatibility layer...
#if (QP_API_VERSION &lt; 730)
//! @deprecated plain 'char' is no longer forbidden in MISRA/AUTOSAR-C++
using char_t = char;
//! @deprecated assertion failure handler
//! Use Q_onError() instead.
#define Q_onAssert(module_, id_) Q_onError(module_, id_)
//! @deprecated #Q_NASSERT preprocessor switch to disable QP assertions
#ifdef Q_NASSERT
// #Q_UNSAFE now replaces the functionality of Q_NASSERT
#define Q_UNSAFE
//! @deprecated general purpose assertion with user-specified ID
//! number that **always** evaluates the `expr_` expression.
#define Q_ALLEGE_ID(id_, expr_) ((void)(expr_))
#else // QP FuSa Subsystem enabled
//! @deprecated general purpose assertion with user-specified ID
//! number that **always** evaluates the `expr_` expression.
//! @note
//! The use of this macro is no longer recommended.
#define Q_ALLEGE_ID(id_, expr_) if (!(expr_)) { \
QF_CRIT_STAT \
QF_CRIT_ENTRY(); \
Q_onError(&amp;Q_this_module_[0], (id_)); \
QF_CRIT_EXIT(); \
} else ((void)0)
#endif
//! @deprecated general purpose assertion without ID number
//! that **always** evaluates the `expr_` expression.
//! Instead of ID number, this macro is based on the standard
//! `__LINE__` macro.
//!
//! @note The use of this macro is no longer recommended.
#define Q_ALLEGE(expr_) Q_ALLEGE_ID(__LINE__, (expr_))
//! Static (compile-time) assertion.
//!
//! @deprecated
//! Use Q_ASSERT_STATIC() or better yet `static_assert()` instead.
//!
#define Q_ASSERT_COMPILE(expr_) Q_ASSERT_STATIC(expr_)
//! @deprecated use QP::QF::NO_MARGIN instead
#define QF_NO_MARGIN QP::QF::NO_MARGIN
//============================================================================
#if (QP_API_VERSION &lt; 691)
//! @deprecated enable the QS global filter
#define QS_FILTER_ON(rec_) QS_GLB_FILTER((rec_))
//! @deprecated disable the QS global filter
#define QS_FILTER_OFF(rec_) QS_GLB_FILTER(-(rec_))
//! @deprecated enable the QS local filter for SM (state machine) object
#define QS_FILTER_SM_OBJ(obj_) (static_cast&lt;void&gt;(0))
//! @deprecated enable the QS local filter for AO (active objects)
#define QS_FILTER_AO_OBJ(obj_) (static_cast&lt;void&gt;(0))
//! @deprecated enable the QS local filter for MP (memory pool) object
#define QS_FILTER_MP_OBJ(obj_) (static_cast&lt;void&gt;(0))
//! @deprecated enable the QS local filter for EQ (event queue) object
#define QS_FILTER_EQ_OBJ(obj_) (static_cast&lt;void&gt;(0))
//! @deprecated enable the QS local filter for TE (time event) object
#define QS_FILTER_TE_OBJ(obj_) (static_cast&lt;void&gt;(0))
#ifdef Q_SPY
//! @deprecated local Filter for a generic application object `obj_`.
#define QS_FILTER_AP_OBJ(obj_) \
(QP::QS::filt_.loc_AP = (obj_))
//! @deprecated begin of a user QS record, instead use QS_BEGIN_ID()
#define QS_BEGIN(rec_, obj_) \
if (QS_GLB_FILTER_(rec_) &amp;&amp; \
((QP::QS::filt_.loc[QP::QS::AP_OBJ] == nullptr) \
|| (QP::QS::filt_.loc_AP == (obj_)))) \
{ \
QS_CRIT_STAT \
QS_CRIT_ENTRY(); \
QP::QS::beginRec_(static_cast&lt;std::uint_fast8_t&gt;(rec_)); \
QS_TIME_PRE_();
//! @deprecated output hex-formatted std::uint32_t to the QS record
#define QS_U32_HEX(width_, data_) \
(QP::QS::u32_fmt_(static_cast&lt;std::uint8_t&gt;( \
(static_cast&lt;std::uint8_t&gt;((width_) &lt;&lt; 4)) | QS_HEX_FMT), (data_)))
#else
#define QS_FILTER_AP_OBJ(obj_) (static_cast&lt;void&gt;(0))
#define QS_BEGIN(rec_, obj_) if (false) {
#define QS_U32_HEX(width_, data_) (Q_UNUSED_PAR(0))
#endif // def Q_SPY
//============================================================================
#if (QP_API_VERSION &lt; 680)
//! @deprecated
//! Macro to specify a tran. in the &quot;me-&gt;&quot; impl-strategy.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! you call tran(Q_STATE_CAST(target_)).
#define Q_TRAN(target_) (me-&gt;tran(Q_STATE_CAST(target_)))
//! @deprecated
//! Macro to specify a tran-to-history in the &quot;me-&gt;&quot; impl-strategy.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! you call tran_hist(Q_STATE_CAST(hist_)).
#define Q_TRAN_HIST(hist_) (me-&gt;tran_hist((hist_)))
//! @deprecated
//! Macro to specify the superstate in the &quot;me-&gt;&quot; impl-strategy.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! you call super(state_)).
#define Q_SUPER(state_) (me-&gt;super(Q_STATE_CAST(state_)))
//! @deprecated
//! Macro to call in a QM state entry-handler. Applicable only to QMSMs.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! the QM-generated code calls qm_entry(Q_STATE_CAST(state_)).
#define QM_ENTRY(state_) (me-&gt;qm_entry((state_)))
//! @deprecated
//! Macro to call in a QM state exit-handler. Applicable only to QMSMs.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! the QM-generated code calls qm_exit(Q_STATE_CAST(state_)).
#define QM_EXIT(state_) (me-&gt;qm_exit((state_)))
//! @deprecated
//! Macro to call in a QM submachine exit-handler. Applicable only to QMSMs.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! the QM-generated code calls qm_sm_exit(Q_STATE_CAST(state_)).
#define QM_SM_EXIT(state_) (me-&gt;qm_sm_exit((state_)))
//! @deprecated
//! Macro to call in a QM state-handler when it executes a tran.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! the QM-generated code calls qm_tran((tatbl_)).
#define QM_TRAN(tatbl_) (me-&gt;qm_tran((tatbl_)))
//! @deprecated
//! Macro to call in a QM state-handler when it executes an initial tran.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! the QM-generated code calls qm_tran_init((tatbl_)).
#define QM_TRAN_INIT(tatbl_) (me-&gt;qm_tran_init((tatbl_)))
//! @deprecated
//! Macro to call in a QM state-handler when it executes a tran-to-history.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! the QM-generated code calls qm_tran_hist((history_), (tatbl_)).
#define QM_TRAN_HIST(history_, tatbl_) \
(me-&gt;qm_tran_hist((history_), (tatbl_)))
//! @deprecated
//! Macro to call in a QM state-handler when it executes an initial tran.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! the QM-generated code calls qm_tran_ep((tatbl_)).
#define QM_TRAN_EP(tatbl_) (me-&gt;qm_tran_ep((tatbl_)))
//! @deprecated
//! Macro to call in a QM state-handler when it executes a tran-to-exit-point.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! the QM-generated code calls qm_tran_xp((xp_), (tatbl_)).
#define QM_TRAN_XP(xp_, tatbl_) (me-&gt;qm_tran_xp((xp_), (tatbl_)))
//! @deprecated
//! Designates the superstate of a given state in a subclass of QP::QMsm.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! the QM-generated code calls qm_super_sub((state_)).
#define QM_SUPER_SUB(state_) (me-&gt;qm_super_sub((state_)))
#endif // QP_API_VERSION &lt; 680
#endif // QP_API_VERSION &lt; 691
#endif // QP_API_VERSION &lt; 700
#endif // QPCPP_HPP_</text>
</file>
</directory>
<!--${src}-->
<directory name="src">
<!--${src::qf}-->
<directory name="qf">
<!--${src::qf::qep_hsm.cpp}-->
<file name="qep_hsm.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
//============================================================================
//! @cond INTERNAL
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qep_hsm&quot;)
// immutable events corresponding to the reserved signals.
static QP::QEvt const l_reservedEvt_[4] {
QP::QEvt(static_cast&lt;QP::QSignal&gt;(QP::QHsm::Q_EMPTY_SIG)),
QP::QEvt(static_cast&lt;QP::QSignal&gt;(QP::QHsm::Q_ENTRY_SIG)),
QP::QEvt(static_cast&lt;QP::QSignal&gt;(QP::QHsm::Q_EXIT_SIG)),
QP::QEvt(static_cast&lt;QP::QSignal&gt;(QP::QHsm::Q_INIT_SIG))
};
} // unnamed namespace
// helper macro to handle reserved event in an QHsm
#define QHSM_RESERVED_EVT_(state_, sig_) \
((*(state_))(this, &amp;l_reservedEvt_[(sig_)]))
// helper macro to trace state entry
#define QS_STATE_ENTRY_(state_, qsId_) \
QS_CRIT_ENTRY(); \
QS_MEM_SYS(); \
QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, (qsId_)) \
QS_OBJ_PRE_(this); \
QS_FUN_PRE_(state_); \
QS_END_PRE_() \
QS_MEM_APP(); \
QS_CRIT_EXIT()
// helper macro to trace state exit
#define QS_STATE_EXIT_(state_, qsId_) \
QS_CRIT_ENTRY(); \
QS_MEM_SYS(); \
QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, (qsId_)) \
QS_OBJ_PRE_(this); \
QS_FUN_PRE_(state_); \
QS_END_PRE_() \
QS_MEM_APP(); \
QS_CRIT_EXIT()
//! @endcond
//============================================================================
$define ${QEP::versionStr[]}
$define ${QEP::QHsm}</text>
</file>
<!--${src::qf::qep_msm.cpp}-->
<file name="qep_msm.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
//============================================================================
//! @cond INTERNAL
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qep_msm&quot;)
// maximum depth of state nesting in a QMsm (including the top level)
static constexpr std::int_fast8_t MAX_NEST_DEPTH_ {6};
// maximum length of transition-action array
static constexpr std::int_fast8_t MAX_TRAN_LENGTH_ {3*MAX_NEST_DEPTH_};
// maximum depth of entry levels in a MSM for tran. to history.
static constexpr std::int_fast8_t MAX_ENTRY_DEPTH_ {4};
// top-state object for QMsm-style state machines
QP::QMState const l_msm_top_s = {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr
};
} // unnamed namespace
//! @endcond
//============================================================================
$define ${QEP::QMsm}</text>
</file>
<!--${src::qf::qf_act.cpp}-->
<file name="qf_act.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
// unnamed namespace for local definitions with internal linkage
namespace {
//Q_DEFINE_THIS_MODULE(&quot;qf_act&quot;)
} // unnamed namespace
$define ${QF::QActive::registry_[QF_MAX_ACTIVE + 1U]}
$define ${QF::QF-pkg}
$define ${QF::types::QF_LOG2}</text>
</file>
<!--${src::qf::qf_actq.cpp}-->
<file name="qf_actq.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
//============================================================================
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qf_actq&quot;)
} // unnamed namespace
$define ${QF::QActive::post_}
$define ${QF::QActive::postLIFO}
$define ${QF::QActive::get_}
$define ${QF::QTicker}</text>
</file>
<!--${src::qf::qf_defer.cpp}-->
<file name="qf_defer.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qf_defer&quot;)
} // unnamed namespace
$define ${QF::QActive::defer}
$define ${QF::QActive::recall}
$define ${QF::QActive::flushDeferred}</text>
</file>
<!--${src::qf::qf_dyn.cpp}-->
<file name="qf_dyn.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
#if (QF_MAX_EPOOL &gt; 0U) // mutable events configured?
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qf_dyn&quot;)
} // unnamed namespace
$define ${QEP::QEvt::ctor}
$define ${QF::QF-dyn}
#endif // (QF_MAX_EPOOL &gt; 0U) mutable events configured</text>
</file>
<!--${src::qf::qf_mem.cpp}-->
<file name="qf_mem.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qf_mem&quot;)
} // unnamed namespace
$define ${QF::QMPool}</text>
</file>
<!--${src::qf::qf_qact.cpp}-->
<file name="qf_qact.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qf_qact&quot;)
} // unnamed namespace
$define ${QF::QActive::QActive}
$define ${QF::QActive::register_}
$define ${QF::QActive::unregister_}</text>
</file>
<!--${src::qf::qf_qmact.cpp}-->
<file name="qf_qmact.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
// unnamed namespace for local definitions with internal linkage
namespace {
//Q_DEFINE_THIS_MODULE(&quot;qf_qmact&quot;)
} // unnamed namespace
$define ${QF::QMActive}</text>
</file>
<!--${src::qf::qf_qeq.cpp}-->
<file name="qf_qeq.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qf_qeq&quot;)
} // unnamed namespace
$define ${QF::QEQueue}</text>
</file>
<!--${src::qf::qf_ps.cpp}-->
<file name="qf_ps.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qf_ps&quot;)
} // unnamed namespace
$define ${QF::QActive::subscrList_}
$define ${QF::QActive::maxPubSignal_}
$define ${QF::QActive::psInit}
$define ${QF::QActive::publish_}
$define ${QF::QActive::subscribe}
$define ${QF::QActive::unsubscribe}
$define ${QF::QActive::unsubscribeAll}</text>
</file>
<!--${src::qf::qf_time.cpp}-->
<file name="qf_time.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qf_time&quot;)
} // unnamed namespace
$define ${QF::QTimeEvt}</text>
</file>
</directory>
<!--${src::qv}-->
<directory name="qv">
<!--${src::qv::qv.cpp}-->
<file name="qv.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
// protection against including this source file in a wrong project
#ifndef QV_HPP_
#error &quot;Source file included in a project NOT based on the QV kernel&quot;
#endif // QV_HPP_
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qv&quot;)
} // unnamed namespace
$define ${QV::QV-base}
$define ${QV::QF-cust}
$define ${QV::QActive}</text>
</file>
</directory>
<!--${src::qk}-->
<directory name="qk">
<!--${src::qk::qk.cpp}-->
<file name="qk.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
// protection against including this source file in a wrong project
#ifndef QK_HPP_
#error &quot;Source file included in a project NOT based on the QK kernel&quot;
#endif // QK_HPP_
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qk&quot;)
} // unnamed namespace
$define ${QK::QK-base}
extern &quot;C&quot; {
$define ${QK-extern-C}
} // extern &quot;C&quot;
$define ${QK::QF-cust}
$define ${QK::QActive}</text>
</file>
</directory>
<!--${src::qxk}-->
<directory name="qxk">
<!--${src::qxk::qxk.cpp}-->
<file name="qxk.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
// protection against including this source file in a wrong project
#ifndef QXK_HPP_
#error &quot;Source file included in a project NOT based on the QXK kernel&quot;
#endif // QXK_HPP_
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qxk&quot;)
} // unnamed namespace
$define ${QXK::QXK-base}
extern &quot;C&quot; {
$define ${QXK-extern-C}
} // extern &quot;C&quot;
$define ${QXK::QF-cust}
$define ${QXK::QActive}</text>
</file>
<!--${src::qxk::qxk_mutex.cpp}-->
<file name="qxk_mutex.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
// protection against including this source file in a wrong project
#ifndef QXK_HPP_
#error &quot;Source file included in a project NOT based on the QXK kernel&quot;
#endif // QXK_HPP_
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qxk_mutex&quot;)
} // unnamed namespace
$define ${QXK::QXMutex}</text>
</file>
<!--${src::qxk::qxk_sema.cpp}-->
<file name="qxk_sema.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
// protection against including this source file in a wrong project
#ifndef QXK_HPP_
#error &quot;Source file included in a project NOT based on the QXK kernel&quot;
#endif // QXK_HPP_
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qxk_sema&quot;)
} // unnamed namespace
$define ${QXK::QXSemaphore}</text>
</file>
<!--${src::qxk::qxk_xthr.cpp}-->
<file name="qxk_xthr.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
// protection against including this source file in a wrong project
#ifndef QXK_HPP_
#error &quot;Source file included in a project NOT based on the QXK kernel&quot;
#endif // QXK_HPP_
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qxk_xthr&quot;)
} // unnamed namespace
$define ${QXK::QXThread}</text>
</file>
</directory>
<!--${src::qs}-->
<directory name="qs">
<!--${src::qs::qs.cpp}-->
<file name="qs.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS package-scope internal interface
#include &quot;qstamp.hpp&quot; // QP time-stamp
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qs&quot;)
} // unnamed namespace
$define ${QS::QS-TX}
#ifndef QF_MEM_ISOLATE
$define ${QS::filters}
#endif
//============================================================================
//! @cond INTERNAL
namespace QP {
namespace QS {
//............................................................................
Attr priv_;
//............................................................................
void glbFilter_(std::int_fast16_t const filter) noexcept {
bool const isRemove = (filter &lt; 0);
std::uint16_t const rec = isRemove
? static_cast&lt;std::uint16_t&gt;(-filter)
: static_cast&lt;std::uint16_t&gt;(filter);
switch (rec) {
case QS_ALL_RECORDS: {
std::uint8_t const tmp = (isRemove ? 0x00U : 0xFFU);
std::uint_fast8_t i;
// set all global filters (partially unrolled loop)
for (i = 0U; i &lt; Q_DIM(filt_.glb); i += 4U) {
filt_.glb[i ] = tmp;
filt_.glb[i + 1U] = tmp;
filt_.glb[i + 2U] = tmp;
filt_.glb[i + 3U] = tmp;
}
if (isRemove) {
// leave the &quot;not maskable&quot; filters enabled,
// see qs.h, Miscellaneous QS records (not maskable)
//
filt_.glb[0] = 0x01U;
filt_.glb[6] = 0x40U;
filt_.glb[7] = 0xFCU;
filt_.glb[8] = 0x7FU;
}
else {
// never turn the last 3 records on (0x7D, 0x7E, 0x7F)
filt_.glb[15] = 0x1FU;
}
break;
}
case QS_SM_RECORDS:
if (isRemove) {
filt_.glb[0] &amp;= static_cast&lt;std::uint8_t&gt;(~0xFEU &amp; 0xFFU);
filt_.glb[1] &amp;= static_cast&lt;std::uint8_t&gt;(~0x03U &amp; 0xFFU);
filt_.glb[6] &amp;= static_cast&lt;std::uint8_t&gt;(~0x80U &amp; 0xFFU);
filt_.glb[7] &amp;= static_cast&lt;std::uint8_t&gt;(~0x03U &amp; 0xFFU);
}
else {
filt_.glb[0] |= 0xFEU;
filt_.glb[1] |= 0x03U;
filt_.glb[6] |= 0x80U;
filt_.glb[7] |= 0x03U;
}
break;
case QS_AO_RECORDS:
if (isRemove) {
filt_.glb[1] &amp;= static_cast&lt;std::uint8_t&gt;(~0xFCU &amp; 0xFFU);
filt_.glb[2] &amp;= static_cast&lt;std::uint8_t&gt;(~0x07U &amp; 0xFFU);
filt_.glb[5] &amp;= static_cast&lt;std::uint8_t&gt;(~0x20U &amp; 0xFFU);
}
else {
filt_.glb[1] |= 0xFCU;
filt_.glb[2] |= 0x07U;
filt_.glb[5] |= 0x20U;
}
break;
case QS_EQ_RECORDS:
if (isRemove) {
filt_.glb[2] &amp;= static_cast&lt;std::uint8_t&gt;(~0x78U &amp; 0xFFU);
filt_.glb[5] &amp;= static_cast&lt;std::uint8_t&gt;(~0x40U &amp; 0xFFU);
}
else {
filt_.glb[2] |= 0x78U;
filt_.glb[5] |= 0x40U;
}
break;
case QS_MP_RECORDS:
if (isRemove) {
filt_.glb[3] &amp;= static_cast&lt;std::uint8_t&gt;(~0x03U &amp; 0xFFU);
filt_.glb[5] &amp;= static_cast&lt;std::uint8_t&gt;(~0x80U &amp; 0xFFU);
}
else {
filt_.glb[3] |= 0x03U;
filt_.glb[5] |= 0x80U;
}
break;
case QS_QF_RECORDS:
if (isRemove) {
filt_.glb[2] &amp;= static_cast&lt;std::uint8_t&gt;(~0x80U &amp; 0xFFU);
filt_.glb[3] &amp;= static_cast&lt;std::uint8_t&gt;(~0xFCU &amp; 0xFFU);
filt_.glb[4] &amp;= static_cast&lt;std::uint8_t&gt;(~0xC0U &amp; 0xFFU);
filt_.glb[5] &amp;= static_cast&lt;std::uint8_t&gt;(~0x1FU &amp; 0xFFU);
}
else {
filt_.glb[2] |= 0x80U;
filt_.glb[3] |= 0xFCU;
filt_.glb[4] |= 0xC0U;
filt_.glb[5] |= 0x1FU;
}
break;
case QS_TE_RECORDS:
if (isRemove) {
filt_.glb[4] &amp;= static_cast&lt;std::uint8_t&gt;(~0x3FU &amp; 0xFFU);
}
else {
filt_.glb[4] |= 0x3FU;
}
break;
case QS_SC_RECORDS:
if (isRemove) {
filt_.glb[6] &amp;= static_cast&lt;std::uint8_t&gt;(~0x3FU &amp; 0xFFU);
}
else {
filt_.glb[6] |= 0x3FU;
}
break;
case QS_SEM_RECORDS:
if (isRemove) {
filt_.glb[8] &amp;= static_cast&lt;std::uint8_t&gt;(~0x80U &amp; 0xFFU);
filt_.glb[9] &amp;= static_cast&lt;std::uint8_t&gt;(~0x07U &amp; 0xFFU);
}
else {
filt_.glb[8] |= 0x80U;
filt_.glb[9] |= 0x07U;
}
break;
case QS_MTX_RECORDS:
if (isRemove) {
filt_.glb[9] &amp;= static_cast&lt;std::uint8_t&gt;(~0xF8U &amp; 0xFFU);
filt_.glb[10] &amp;= static_cast&lt;std::uint8_t&gt;(~0x01U &amp; 0xFFU);
}
else {
filt_.glb[9] |= 0xF8U;
filt_.glb[10] |= 0x01U;
}
break;
case QS_U0_RECORDS:
if (isRemove) {
filt_.glb[12] &amp;= static_cast&lt;std::uint8_t&gt;(~0xF0U &amp; 0xFFU);
filt_.glb[13] &amp;= static_cast&lt;std::uint8_t&gt;(~0x01U &amp; 0xFFU);
}
else {
filt_.glb[12] |= 0xF0U;
filt_.glb[13] |= 0x01U;
}
break;
case QS_U1_RECORDS:
if (isRemove) {
filt_.glb[13] &amp;= static_cast&lt;std::uint8_t&gt;(~0x3EU &amp; 0xFFU);
}
else {
filt_.glb[13] |= 0x3EU;
}
break;
case QS_U2_RECORDS:
if (isRemove) {
filt_.glb[13] &amp;= static_cast&lt;std::uint8_t&gt;(~0xC0U &amp; 0xFFU);
filt_.glb[14] &amp;= static_cast&lt;std::uint8_t&gt;(~0x07U &amp; 0xFFU);
}
else {
filt_.glb[13] |= 0xC0U;
filt_.glb[14] |= 0x07U;
}
break;
case QS_U3_RECORDS:
if (isRemove) {
filt_.glb[14] &amp;= static_cast&lt;std::uint8_t&gt;(~0xF8U &amp; 0xFFU);
}
else {
filt_.glb[14] |= 0xF8U;
}
break;
case QS_U4_RECORDS:
if (isRemove) {
filt_.glb[15] &amp;= static_cast&lt;std::uint8_t&gt;(~0x1FU &amp; 0xFFU);
}
else {
filt_.glb[15] |= 0x1FU;
}
break;
case QS_UA_RECORDS:
if (isRemove) {
filt_.glb[12] &amp;= static_cast&lt;std::uint8_t&gt;(~0xF0U &amp; 0xFFU);
filt_.glb[13] = 0U;
filt_.glb[14] = 0U;
filt_.glb[15] &amp;= static_cast&lt;std::uint8_t&gt;(~0x1FU &amp; 0xFFU);
}
else {
filt_.glb[12] |= 0xF0U;
filt_.glb[13] |= 0xFFU;
filt_.glb[14] |= 0xFFU;
filt_.glb[15] |= 0x1FU;
}
break;
default: {
QS_CRIT_STAT
QS_CRIT_ENTRY();
// QS rec number must be below 0x7D, so no need for escaping
Q_ASSERT_INCRIT(210, rec &lt; 0x7DU);
QS_CRIT_EXIT();
if (isRemove) {
filt_.glb[rec &gt;&gt; 3U]
&amp;= static_cast&lt;std::uint8_t&gt;(~(1U &lt;&lt; (rec &amp; 7U)) &amp; 0xFFU);
}
else {
filt_.glb[rec &gt;&gt; 3U]
|= static_cast&lt;std::uint8_t&gt;(1U &lt;&lt; (rec &amp; 7U));
// never turn the last 3 records on (0x7D, 0x7E, 0x7F)
filt_.glb[15] &amp;= 0x1FU;
}
break;
}
}
}
//............................................................................
void locFilter_(std::int_fast16_t const filter) noexcept {
bool const isRemove = (filter &lt; 0);
std::uint16_t const qsId = isRemove
? static_cast&lt;std::uint16_t&gt;(-filter)
: static_cast&lt;std::uint16_t&gt;(filter);
std::uint8_t const tmp = (isRemove ? 0x00U : 0xFFU);
std::uint_fast8_t i;
switch (qsId) {
case QS_ALL_IDS:
// set all local filters (partially unrolled loop)
for (i = 0U; i &lt; Q_DIM(filt_.loc); i += 4U) {
filt_.loc[i ] = tmp;
filt_.loc[i + 1U] = tmp;
filt_.loc[i + 2U] = tmp;
filt_.loc[i + 3U] = tmp;
}
break;
case QS_AO_IDS:
for (i = 0U; i &lt; 8U; i += 4U) {
filt_.loc[i ] = tmp;
filt_.loc[i + 1U] = tmp;
filt_.loc[i + 2U] = tmp;
filt_.loc[i + 3U] = tmp;
}
break;
case QS_EP_IDS:
i = 8U;
filt_.loc[i ] = tmp;
filt_.loc[i + 1U] = tmp;
break;
case QS_AP_IDS:
i = 12U;
filt_.loc[i ] = tmp;
filt_.loc[i + 1U] = tmp;
filt_.loc[i + 2U] = tmp;
filt_.loc[i + 3U] = tmp;
break;
default: {
QS_CRIT_STAT
QS_CRIT_ENTRY();
// qsId must be in range
Q_ASSERT_INCRIT(310, qsId &lt; 0x7FU);
QS_CRIT_EXIT();
if (isRemove) {
filt_.loc[qsId &gt;&gt; 3U] &amp;=
static_cast&lt;std::uint8_t&gt;(
~(1U &lt;&lt; (qsId &amp; 7U)) &amp; 0xFFU);
}
else {
filt_.loc[qsId &gt;&gt; 3U]
|= (1U &lt;&lt; (qsId &amp; 7U));
}
break;
}
}
filt_.loc[0] |= 0x01U; // leave QS_ID == 0 always on
}
//............................................................................
void beginRec_(std::uint_fast8_t const rec) noexcept {
std::uint8_t const b = priv_.seq + 1U;
std::uint8_t chksum = 0U; // reset the checksum
std::uint8_t * const buf = priv_.buf; // put in a temporary (register)
QSCtr head = priv_.head; // put in a temporary (register)
QSCtr const end = priv_.end; // put in a temporary (register)
priv_.seq = b; // store the incremented sequence num
priv_.used = (priv_.used + 2U); // 2 bytes about to be added
QS_INSERT_ESC_BYTE_(b)
chksum += static_cast&lt;std::uint8_t&gt;(rec);
QS_INSERT_BYTE_(static_cast&lt;std::uint8_t&gt;(rec)) // no need for escaping
priv_.head = head; // save the head
priv_.chksum = chksum; // save the checksum
}
//............................................................................
void endRec_() noexcept {
std::uint8_t * const buf = priv_.buf; // put in a temporary (register)
QSCtr head = priv_.head;
QSCtr const end = priv_.end;
std::uint8_t b = priv_.chksum;
b ^= 0xFFU; // invert the bits in the checksum
priv_.used = (priv_.used + 2U); // 2 bytes about to be added
if ((b != QS_FRAME) &amp;&amp; (b != QS_ESC)) {
QS_INSERT_BYTE_(b)
}
else {
QS_INSERT_BYTE_(QS_ESC)
QS_INSERT_BYTE_(b ^ QS_ESC_XOR)
priv_.used = (priv_.used + 1U); // account for the ESC byte
}
QS_INSERT_BYTE_(QS_FRAME) // do not escape this QS_FRAME
priv_.head = head; // save the head
if (priv_.used &gt; end) { // overrun over the old data?
priv_.used = end; // the whole buffer is used
priv_.tail = head; // shift the tail to the old data
}
}
//............................................................................
void u8_raw_(std::uint8_t const d) noexcept {
std::uint8_t chksum = priv_.chksum; // put in a temporary (register)
std::uint8_t * const buf = priv_.buf; // put in a temporary (register)
QSCtr head = priv_.head; // put in a temporary (register)
QSCtr const end = priv_.end; // put in a temporary (register)
priv_.used = (priv_.used + 1U); // 1 byte about to be added
QS_INSERT_ESC_BYTE_(d)
priv_.head = head; // save the head
priv_.chksum = chksum; // save the checksum
}
//............................................................................
void u8u8_raw_(
std::uint8_t const d1,
std::uint8_t const d2) noexcept
{
std::uint8_t chksum = priv_.chksum; // put in a temporary (register)
std::uint8_t * const buf = priv_.buf; // put in a temporary (register)
QSCtr head = priv_.head; // put in a temporary (register)
QSCtr const end = priv_.end; // put in a temporary (register)
priv_.used = (priv_.used + 2U); // 2 bytes about to be added
QS_INSERT_ESC_BYTE_(d1)
QS_INSERT_ESC_BYTE_(d2)
priv_.head = head; // save the head
priv_.chksum = chksum; // save the checksum
}
//............................................................................
void u16_raw_(std::uint16_t d) noexcept {
std::uint8_t b = static_cast&lt;std::uint8_t&gt;(d);
std::uint8_t chksum = priv_.chksum; // put in a temporary (register)
std::uint8_t * const buf = priv_.buf; // put in a temporary (register)
QSCtr head = priv_.head; // put in a temporary (register)
QSCtr const end = priv_.end; // put in a temporary (register)
priv_.used = (priv_.used + 2U); // 2 bytes about to be added
QS_INSERT_ESC_BYTE_(b)
d &gt;&gt;= 8U;
b = static_cast&lt;std::uint8_t&gt;(d);
QS_INSERT_ESC_BYTE_(b)
priv_.head = head; // save the head
priv_.chksum = chksum; // save the checksum
}
//............................................................................
void u32_raw_(std::uint32_t d) noexcept {
std::uint8_t chksum = priv_.chksum; // put in a temporary (register)
std::uint8_t * const buf = priv_.buf; // put in a temporary (register)
QSCtr head = priv_.head; // put in a temporary (register)
QSCtr const end = priv_.end; // put in a temporary (register)
priv_.used = (priv_.used + 4U); // 4 bytes about to be added
for (std::uint_fast8_t i = 4U; i != 0U; --i) {
std::uint8_t const b = static_cast&lt;std::uint8_t&gt;(d);
QS_INSERT_ESC_BYTE_(b)
d &gt;&gt;= 8U;
}
priv_.head = head; // save the head
priv_.chksum = chksum; // save the checksum
}
//............................................................................
void obj_raw_(void const * const obj) noexcept {
#if (QS_OBJ_PTR_SIZE == 1U)
u8_raw_(reinterpret_cast&lt;std::uint8_t&gt;(obj));
#elif (QS_OBJ_PTR_SIZE == 2U)
u16_raw_(reinterpret_cast&lt;std::uint16_t&gt;(obj));
#elif (QS_OBJ_PTR_SIZE == 4U)
u32_raw_(reinterpret_cast&lt;std::uint32_t&gt;(obj));
#elif (QS_OBJ_PTR_SIZE == 8U)
u64_raw_(reinterpret_cast&lt;std::uint64_t&gt;(obj));
#else
u32_raw_(reinterpret_cast&lt;std::uint32_t&gt;(obj));
#endif
}
//............................................................................
void str_raw_(char const * s) noexcept {
std::uint8_t b = static_cast&lt;std::uint8_t&gt;(*s);
std::uint8_t chksum = priv_.chksum; // put in a temporary (register)
std::uint8_t * const buf = priv_.buf; // put in a temporary (register)
QSCtr head = priv_.head; // put in a temporary (register)
QSCtr const end = priv_.end; // put in a temporary (register)
QSCtr used = priv_.used; // put in a temporary (register)
while (b != 0U) {
chksum += b; // update checksum
QS_INSERT_BYTE_(b) // ASCII characters don't need escaping
++s;
b = static_cast&lt;std::uint8_t&gt;(*s);
++used;
}
QS_INSERT_BYTE_(0U) // zero-terminate the string
++used;
priv_.head = head; // save the head
priv_.chksum = chksum; // save the checksum
priv_.used = used; // save # of used buffer space
}
//............................................................................
void u8_fmt_(
std::uint8_t const format,
std::uint8_t const d) noexcept
{
std::uint8_t chksum = priv_.chksum; // put in a temporary (register)
std::uint8_t *const buf = priv_.buf; // put in a temporary (register)
QSCtr head = priv_.head; // put in a temporary (register)
QSCtr const end = priv_.end; // put in a temporary (register)
priv_.used = (priv_.used + 2U); // 2 bytes about to be added
QS_INSERT_ESC_BYTE_(format)
QS_INSERT_ESC_BYTE_(d)
priv_.head = head; // save the head
priv_.chksum = chksum; // save the checksum
}
//............................................................................
void u16_fmt_(
std::uint8_t format,
std::uint16_t d) noexcept
{
std::uint8_t chksum = priv_.chksum; // put in a temporary (register)
std::uint8_t * const buf = priv_.buf; // put in a temporary (register)
QSCtr head = priv_.head; // put in a temporary (register)
QSCtr const end = priv_.end; // put in a temporary (register)
priv_.used = (priv_.used + 3U); // 3 bytes about to be added
QS_INSERT_ESC_BYTE_(format)
format = static_cast&lt;std::uint8_t&gt;(d);
QS_INSERT_ESC_BYTE_(format)
d &gt;&gt;= 8U;
format = static_cast&lt;std::uint8_t&gt;(d);
QS_INSERT_ESC_BYTE_(format)
priv_.head = head; // save the head
priv_.chksum = chksum; // save the checksum
}
//............................................................................
void u32_fmt_(
std::uint8_t format,
std::uint32_t d) noexcept
{
std::uint8_t chksum = priv_.chksum; // put in a temporary (register)
std::uint8_t * const buf = priv_.buf; // put in a temporary (register)
QSCtr head = priv_.head; // put in a temporary (register)
QSCtr const end = priv_.end; // put in a temporary (register)
priv_.used = (priv_.used + 5U); // 5 bytes about to be added
QS_INSERT_ESC_BYTE_(format) // insert the format byte
for (std::uint_fast8_t i = 4U; i != 0U; --i) {
format = static_cast&lt;std::uint8_t&gt;(d);
QS_INSERT_ESC_BYTE_(format)
d &gt;&gt;= 8U;
}
priv_.head = head; // save the head
priv_.chksum = chksum; // save the checksum
}
//............................................................................
void str_fmt_(char const * s) noexcept {
std::uint8_t b = static_cast&lt;std::uint8_t&gt;(*s);
std::uint8_t chksum = static_cast&lt;std::uint8_t&gt;(
priv_.chksum + static_cast&lt;std::uint8_t&gt;(STR_T));
std::uint8_t * const buf = priv_.buf; // put in a temporary (register)
QSCtr head = priv_.head; // put in a temporary (register)
QSCtr const end = priv_.end; // put in a temporary (register)
QSCtr used = priv_.used; // put in a temporary (register)
used += 2U; // the format byte and the terminating-0
QS_INSERT_BYTE_(static_cast&lt;std::uint8_t&gt;(STR_T))
while (b != 0U) {
// ASCII characters don't need escaping
chksum += b; // update checksum
QS_INSERT_BYTE_(b)
++s;
b = static_cast&lt;std::uint8_t&gt;(*s);
++used;
}
QS_INSERT_BYTE_(0U) // zero-terminate the string
priv_.head = head; // save the head
priv_.chksum = chksum; // save the checksum
priv_.used = used; // save # of used buffer space
}
//............................................................................
void mem_fmt_(
std::uint8_t const * blk,
std::uint8_t size) noexcept
{
std::uint8_t b = static_cast&lt;std::uint8_t&gt;(MEM_T);
std::uint8_t chksum = priv_.chksum + b;
std::uint8_t * const buf = priv_.buf; // put in a temporary (register)
QSCtr head = priv_.head; // put in a temporary (register)
QSCtr const end = priv_.end; // put in a temporary (register)
priv_.used = (priv_.used + size + 2U); // size+2 bytes to be added
QS_INSERT_BYTE_(b)
QS_INSERT_ESC_BYTE_(size)
// output the 'size' number of bytes
for (; size != 0U; --size) {
b = *blk;
QS_INSERT_ESC_BYTE_(b)
++blk;
}
priv_.head = head; // save the head
priv_.chksum = chksum; // save the checksum
}
//............................................................................
void sig_dict_pre_(
QSignal const sig,
void const * const obj,
char const * const name) noexcept
{
QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QS_SIG_DICT));
QS_SIG_PRE_(sig);
QS_OBJ_PRE_(obj);
QS_STR_PRE_((*name == '&amp;') ? &amp;name[1] : name);
endRec_();
QS_MEM_APP();
QS_CRIT_EXIT();
onFlush();
}
//............................................................................
void obj_dict_pre_(
void const * const obj,
char const * const name) noexcept
{
QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QS_OBJ_DICT));
QS_OBJ_PRE_(obj);
QS_STR_PRE_((*name == '&amp;') ? &amp;name[1] : name);
endRec_();
QS_MEM_APP();
QS_CRIT_EXIT();
onFlush();
}
//............................................................................
void obj_arr_dict_pre_(
void const * const obj,
std::uint_fast16_t const idx,
char const * const name) noexcept
{
QS_CRIT_STAT
QS_CRIT_ENTRY();
Q_REQUIRE_INCRIT(400, idx &lt; 1000U);
QS_CRIT_EXIT();
// format idx into a char buffer as &quot;xxx\0&quot;
std::uint8_t idx_str[4];
std::uint_fast16_t tmp = idx;
std::uint8_t i;
idx_str[3] = 0U; // zero-terminate
idx_str[2] = static_cast&lt;std::uint8_t&gt;(
static_cast&lt;std::uint8_t&gt;('0') + (tmp % 10U));
tmp /= 10U;
idx_str[1] = static_cast&lt;std::uint8_t&gt;(
static_cast&lt;std::uint8_t&gt;('0') + (tmp % 10U));
if (idx_str[1] == static_cast&lt;std::uint8_t&gt;('0')) {
i = 2U;
}
else {
tmp /= 10U;
idx_str[0] = static_cast&lt;std::uint8_t&gt;(
static_cast&lt;std::uint8_t&gt;('0') + (tmp % 10U));
if (idx_str[0] == static_cast&lt;std::uint8_t&gt;('0')) {
i = 1U;
}
else {
i = 0U;
}
}
std::uint8_t j = ((*name == '&amp;') ? 1U : 0U);
QS_CRIT_ENTRY();
QS_MEM_SYS();
beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QS_OBJ_DICT));
QS_OBJ_PRE_(obj);
for (; name[j] != '\0'; ++j) {
QS_U8_PRE_(name[j]);
if (name[j] == '[') {
++j;
break;
}
}
for (; idx_str[i] != 0U; ++i) {
QS_U8_PRE_(idx_str[i]);
}
// skip chars until ']'
for (; name[j] != '\0'; ++j) {
if (name[j] == ']') {
break;
}
}
for (; name[j] != '\0'; ++j) {
QS_U8_PRE_(name[j]);
}
QS_U8_PRE_(0U); // zero-terminate
endRec_();
QS_MEM_APP();
QS_CRIT_EXIT();
onFlush();
}
//............................................................................
void fun_dict_pre_(
QSpyFunPtr fun,
char const * const name) noexcept
{
QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QS_FUN_DICT));
QS_FUN_PRE_(fun);
QS_STR_PRE_((*name == '&amp;') ? &amp;name[1] : name);
endRec_();
QS_MEM_APP();
QS_CRIT_EXIT();
onFlush();
}
//............................................................................
void usr_dict_pre_(
enum_t const rec,
char const * const name) noexcept
{
QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QS_USR_DICT));
QS_U8_PRE_(rec);
QS_STR_PRE_(name);
endRec_();
QS_MEM_APP();
QS_CRIT_EXIT();
onFlush();
}
//............................................................................
void enum_dict_pre_(
enum_t const value,
std::uint8_t const group,
char const * const name) noexcept
{
QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QS_ENUM_DICT));
QS_2U8_PRE_(static_cast&lt;std::uint8_t&gt;(value), group);
QS_STR_PRE_(name);
endRec_();
QS_MEM_APP();
QS_CRIT_EXIT();
onFlush();
}
//............................................................................
void assertion_pre_(
char const * const module,
int_t const id,
std::uint32_t const delay) noexcept
{
// NOTE: called in a critical section
beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QS_ASSERT_FAIL));
QS_TIME_PRE_();
QS_U16_PRE_(id);
QS_STR_PRE_((module != nullptr) ? module : &quot;?&quot;);
endRec_();
onFlush();
// busy-wait until all QS data makes it over to the host
for (std::uint32_t volatile ctr = delay; ctr &gt; 0U; ) {
ctr = (ctr - 1U);
}
QS::onCleanup();
}
//............................................................................
void crit_entry_pre_() noexcept {
beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QS_QF_CRIT_ENTRY));
QS_TIME_PRE_();
priv_.critNest = (priv_.critNest + 1U);
QS_U8_PRE_(priv_.critNest);
endRec_();
}
//............................................................................
void crit_exit_pre_() noexcept {
beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QS_QF_CRIT_EXIT));
QS_TIME_PRE_();
QS_U8_PRE_(QS::priv_.critNest);
priv_.critNest = (priv_.critNest - 1U);
endRec_();
}
//............................................................................
void isr_entry_pre_(
std::uint8_t const isrnest,
std::uint8_t const prio) noexcept
{
beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QS_QF_ISR_ENTRY));
QS_TIME_PRE_();
QS_U8_PRE_(isrnest);
QS_U8_PRE_(prio);
endRec_();
}
//............................................................................
void isr_exit_pre_(
std::uint8_t const isrnest,
std::uint8_t const prio) noexcept
{
beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QS_QF_ISR_EXIT));
QS_TIME_PRE_();
QS_U8_PRE_(isrnest);
QS_U8_PRE_(prio);
endRec_();
}
//............................................................................
void target_info_pre_(std::uint8_t const isReset) {
// NOTE: called in a critical section
static constexpr std::uint8_t ZERO = static_cast&lt;std::uint8_t&gt;('0');
static std::uint8_t const * const TIME =
reinterpret_cast&lt;std::uint8_t const *&gt;(&amp;BUILD_TIME[0]);
static std::uint8_t const * const DATE =
reinterpret_cast&lt;std::uint8_t const *&gt;(&amp;BUILD_DATE[0]);
beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QS_TARGET_INFO));
u8_raw_(isReset);
static union {
std::uint16_t u16;
std::uint8_t u8[2];
} endian_test;
endian_test.u16 = 0x0102U;
// big endian ? add the 0x8000U flag
QS_U16_PRE_(((endian_test.u8[0] == 0x01U)
? (0x8000U | QP_VERSION)
: QP_VERSION)); // target endianness + version number
// send the object sizes...
u8_raw_(Q_SIGNAL_SIZE
| static_cast&lt;std::uint8_t&gt;(QF_EVENT_SIZ_SIZE &lt;&lt; 4U));
#ifdef QF_EQUEUE_CTR_SIZE
u8_raw_(QF_EQUEUE_CTR_SIZE
| static_cast&lt;std::uint8_t&gt;(QF_TIMEEVT_CTR_SIZE &lt;&lt; 4U));
#else
QS::u8_raw_(static_cast&lt;std::uint8_t&gt;(QF_TIMEEVT_CTR_SIZE &lt;&lt; 4U));
#endif // ifdef QF_EQUEUE_CTR_SIZE
#ifdef QF_MPOOL_CTR_SIZE
QS::u8_raw_(QF_MPOOL_SIZ_SIZE
| static_cast&lt;std::uint8_t&gt;(QF_MPOOL_CTR_SIZE &lt;&lt; 4U));
#else
QS::u8_raw_(0U);
#endif // ifdef QF_MPOOL_CTR_SIZE
QS::u8_raw_(QS_OBJ_PTR_SIZE | (QS_FUN_PTR_SIZE &lt;&lt; 4U));
QS::u8_raw_(QS_TIME_SIZE);
// send the bounds...
QS::u8_raw_(QF_MAX_ACTIVE);
QS::u8_raw_(QF_MAX_EPOOL | (QF_MAX_TICK_RATE &lt;&lt; 4U));
// send the build time in three bytes (sec, min, hour)...
QS::u8_raw_((10U * (TIME[6] - ZERO)) + (TIME[7] - ZERO));
QS::u8_raw_((10U * (TIME[3] - ZERO)) + (TIME[4] - ZERO));
if (BUILD_TIME[0] == static_cast&lt;std::uint8_t&gt;(' ')) {
QS::u8_raw_(TIME[1] - ZERO);
}
else {
QS::u8_raw_((10U * (TIME[0] - ZERO)) + (TIME[1] - ZERO));
}
// send the build date in three bytes (day, month, year) ...
if (BUILD_DATE[4] == static_cast&lt;std::uint8_t&gt;(' ')) {
QS::u8_raw_(DATE[5] - ZERO);
}
else {
QS::u8_raw_((10U * (DATE[4] - ZERO)) + (DATE[5] - ZERO));
}
// convert the 3-letter month to a number 1-12 ...
std::uint8_t b;
switch (DATE[0] + DATE[1] + DATE[2]) {
case 'J' + 'a' +'n':
b = 1U;
break;
case 'F' + 'e' + 'b':
b = 2U;
break;
case 'M' + 'a' +'r':
b = 3U;
break;
case 'A' + 'p' + 'r':
b = 4U;
break;
case 'M' + 'a' + 'y':
b = 5U;
break;
case 'J' + 'u' + 'n':
b = 6U;
break;
case 'J' + 'u' + 'l':
b = 7U;
break;
case 'A' + 'u' + 'g':
b = 8U;
break;
case 'S' + 'e' + 'p':
b = 9U;
break;
case 'O' + 'c' + 't':
b = 10U;
break;
case 'N' + 'o' + 'v':
b = 11U;
break;
case 'D' + 'e' + 'c':
b = 12U;
break;
default:
b = 0U;
break;
}
QS::u8_raw_(b); // store the month
QS::u8_raw_((10U * (DATE[9] - ZERO)) + (DATE[10] - ZERO));
QS::endRec_();
}
} // namespace QS
} // namespace QP
//! @endcond</text>
</file>
<!--${src::qs::qs_64bit.cpp}-->
<file name="qs_64bit.cpp">
<text>#define QP_IMPL // this is QF/QK implementation
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS package-scope internal interface
//============================================================================
//! @cond INTERNAL
namespace QP {
namespace QS {
//${QS::QS-tx-64bit::u64_raw_} ...............................................
void u64_raw_(std::uint64_t d) noexcept {
std::uint8_t chksum = priv_.chksum;
std::uint8_t * const buf = priv_.buf;
QSCtr head = priv_.head;
QSCtr const end = priv_.end;
priv_.used = (priv_.used + 8U); // 8 bytes are about to be added
for (std::int_fast8_t i = 8U; i != 0U; --i) {
std::uint8_t const b = static_cast&lt;std::uint8_t&gt;(d);
QS_INSERT_ESC_BYTE_(b)
d &gt;&gt;= 8U;
}
priv_.head = head; // save the head
priv_.chksum = chksum; // save the checksum
}
//${QS::QS-tx-64bit::u64_fmt_} ...............................................
void u64_fmt_(
std::uint8_t format,
std::uint64_t d) noexcept
{
std::uint8_t chksum = priv_.chksum;
std::uint8_t * const buf = priv_.buf;
QSCtr head = priv_.head;
QSCtr const end = priv_.end;
priv_.used = (priv_.used + 9U); // 9 bytes are about to be added
QS_INSERT_ESC_BYTE_(format) // insert the format byte
for (std::int_fast8_t i = 8U; i != 0U; --i) {
format = static_cast&lt;std::uint8_t&gt;(d);
QS_INSERT_ESC_BYTE_(format)
d &gt;&gt;= 8U;
}
priv_.head = head; // save the head
priv_.chksum = chksum; // save the checksum
}
} // namespace QS
} // namespace QP
//! @endcond</text>
</file>
<!--${src::qs::qs_fp.cpp}-->
<file name="qs_fp.cpp">
<text>#define QP_IMPL // this is QF/QK implementation
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS package-scope internal interface
//============================================================================
//! @cond INTERNAL
namespace QP {
namespace QS {
//${QS::QS-tx-fp::f32_fmt_} ..................................................
void f32_fmt_(
std::uint8_t format,
float32_t f) noexcept
{
union F32Rep {
float32_t f;
std::uint32_t u;
} fu32; // the internal binary representation
std::uint8_t chksum = priv_.chksum; // put in a temporary (register)
std::uint8_t * const buf = priv_.buf; // put in a temporary (register)
QSCtr head = priv_.head; // put in a temporary (register)
QSCtr const end = priv_.end; // put in a temporary (register)
fu32.f = f; // assign the binary representation
priv_.used = (priv_.used + 5U); // 5 bytes about to be added
QS_INSERT_ESC_BYTE_(format) // insert the format byte
for (std::uint_fast8_t i = 4U; i != 0U; --i) {
format = static_cast&lt;std::uint8_t&gt;(fu32.u);
QS_INSERT_ESC_BYTE_(format)
fu32.u &gt;&gt;= 8U;
}
priv_.head = head; // save the head
priv_.chksum = chksum; // save the checksum
}
//${QS::QS-tx-fp::f64_fmt_} ..................................................
void f64_fmt_(
std::uint8_t format,
float64_t d) noexcept
{
union F64Rep {
float64_t d;
std::uint32_t u[2];
} fu64; // the internal binary representation
std::uint8_t chksum = priv_.chksum;
std::uint8_t * const buf = priv_.buf;
QSCtr head = priv_.head;
QSCtr const end = priv_.end;
std::uint32_t i;
// static constant untion to detect endianness of the machine
static union U32Rep {
std::uint32_t u32;
std::uint8_t u8;
} const endian = { 1U };
fu64.d = d; // assign the binary representation
// is this a big-endian machine?
if (endian.u8 == 0U) {
// swap fu64.u[0] &lt;-&gt; fu64.u[1]...
i = fu64.u[0];
fu64.u[0] = fu64.u[1];
fu64.u[1] = i;
}
priv_.used = (priv_.used + 9U); // 9 bytes about to be added
QS_INSERT_ESC_BYTE_(format) // insert the format byte
// output 4 bytes from fu64.u[0]...
for (i = 4U; i != 0U; --i) {
QS_INSERT_ESC_BYTE_(static_cast&lt;std::uint8_t&gt;(fu64.u[0]))
fu64.u[0] &gt;&gt;= 8U;
}
// output 4 bytes from fu64.u[1]...
for (i = 4U; i != 0U; --i) {
QS_INSERT_ESC_BYTE_(static_cast&lt;std::uint8_t&gt;(fu64.u[1]))
fu64.u[1] &gt;&gt;= 8U;
}
priv_.head = head; // update the head
priv_.chksum = chksum; // update the checksum
}
} // namespace QS
} // namespace QP
//! @endcond</text>
</file>
<!--${src::qs::qs_rx.cpp}-->
<file name="qs_rx.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS package-scope internal interface
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
//============================================================================
//! @cond INTERNAL
namespace { // unnamed local namespace
Q_DEFINE_THIS_MODULE(&quot;qs_rx&quot;)
enum RxStateEnum : std::uint8_t {
ERROR_STATE,
WAIT4_SEQ,
WAIT4_REC,
WAIT4_INFO_FRAME,
WAIT4_CMD_ID,
WAIT4_CMD_PARAM1,
WAIT4_CMD_PARAM2,
WAIT4_CMD_PARAM3,
WAIT4_CMD_FRAME,
WAIT4_RESET_FRAME,
WAIT4_TICK_RATE,
WAIT4_TICK_FRAME,
WAIT4_PEEK_OFFS,
WAIT4_PEEK_SIZE,
WAIT4_PEEK_NUM,
WAIT4_PEEK_FRAME,
WAIT4_POKE_OFFS,
WAIT4_POKE_SIZE,
WAIT4_POKE_NUM,
WAIT4_POKE_DATA,
WAIT4_POKE_FRAME,
WAIT4_FILL_DATA,
WAIT4_FILL_FRAME,
WAIT4_FILTER_LEN,
WAIT4_FILTER_DATA,
WAIT4_FILTER_FRAME,
WAIT4_OBJ_KIND,
WAIT4_OBJ_ADDR,
WAIT4_OBJ_FRAME,
WAIT4_QUERY_KIND,
WAIT4_QUERY_FRAME,
WAIT4_EVT_PRIO,
WAIT4_EVT_SIG,
WAIT4_EVT_LEN,
WAIT4_EVT_PAR,
WAIT4_EVT_FRAME
#ifdef Q_UTEST
,
WAIT4_TEST_SETUP_FRAME,
WAIT4_TEST_TEARDOWN_FRAME,
WAIT4_TEST_PROBE_DATA,
WAIT4_TEST_PROBE_ADDR,
WAIT4_TEST_PROBE_FRAME,
WAIT4_TEST_CONTINUE_FRAME
#endif // Q_UTEST
};
// internal helper functions...
static void rxParseData_(std::uint8_t const b) noexcept;
static void rxHandleGoodFrame_(std::uint8_t const state);
static void rxHandleBadFrame_(std::uint8_t const state) noexcept;
static void rxReportAck_(enum QP::QSpyRxRecords const recId) noexcept;
static void rxReportError_(std::uint8_t const code) noexcept;
static void rxReportDone_(enum QP::QSpyRxRecords const recId) noexcept;
static void queryCurrObj_(std::uint8_t obj_kind) noexcept;
static void rxPoke_() noexcept;
// Internal QS-RX function to take a tran. in the QS-RX FSM
static inline void tran_(RxStateEnum const target) noexcept {
QP::QS::rxPriv_.state = static_cast&lt;std::uint8_t&gt;(target);
}
} // unnamed namespace
#ifndef QF_MEM_ISOLATE
namespace QP {
namespace QS {
RxAttr rxPriv_;
} // namespace QS
} // namespace QP
#endif // QF_MEM_ISOLATE
//! @endcond
//============================================================================
$define ${QS::QS-RX}
//============================================================================
//! @cond INTERNAL
namespace { // unnamed local namespace
//............................................................................
static void rxParseData_(std::uint8_t const b) noexcept {
switch (QP::QS::rxPriv_.state) {
case WAIT4_SEQ: {
++QP::QS::rxPriv_.seq;
if (QP::QS::rxPriv_.seq != b) { // not the expected sequence?
rxReportError_(0x42U);
QP::QS::rxPriv_.seq = b; // update the sequence
}
tran_(WAIT4_REC);
break;
}
case WAIT4_REC: {
switch (b) {
case QP::QS_RX_INFO:
tran_(WAIT4_INFO_FRAME);
break;
case QP::QS_RX_COMMAND:
tran_(WAIT4_CMD_ID);
break;
case QP::QS_RX_RESET:
tran_(WAIT4_RESET_FRAME);
break;
case QP::QS_RX_TICK:
tran_(WAIT4_TICK_RATE);
break;
case QP::QS_RX_PEEK:
if (QP::QS::rxPriv_.currObj[QP::QS::AP_OBJ] != nullptr) {
QP::QS::rxPriv_.var.peek.offs = 0U;
QP::QS::rxPriv_.var.peek.idx = 0U;
tran_(WAIT4_PEEK_OFFS);
}
else {
rxReportError_(
static_cast&lt;std::uint8_t&gt;(QP::QS_RX_PEEK));
tran_(ERROR_STATE);
}
break;
case QP::QS_RX_POKE:
case QP::QS_RX_FILL:
QP::QS::rxPriv_.var.poke.fill =
(b == static_cast&lt;std::uint8_t&gt;(QP::QS_RX_FILL))
? 1U : 0U;
if (QP::QS::rxPriv_.currObj[QP::QS::AP_OBJ] != nullptr) {
QP::QS::rxPriv_.var.poke.offs = 0U;
QP::QS::rxPriv_.var.poke.idx = 0U;
tran_(WAIT4_POKE_OFFS);
}
else {
rxReportError_(
(QP::QS::rxPriv_.var.poke.fill != 0U)
? static_cast&lt;std::uint8_t&gt;(QP::QS_RX_FILL)
: static_cast&lt;std::uint8_t&gt;(QP::QS_RX_POKE));
tran_(ERROR_STATE);
}
break;
case QP::QS_RX_GLB_FILTER: // intentionally fall-through
case QP::QS_RX_LOC_FILTER:
QP::QS::rxPriv_.var.flt.recId = b;
tran_(WAIT4_FILTER_LEN);
break;
case QP::QS_RX_AO_FILTER: // intentionally fall-through
case QP::QS_RX_CURR_OBJ:
QP::QS::rxPriv_.var.obj.recId = b;
tran_(WAIT4_OBJ_KIND);
break;
case QP::QS_RX_QUERY_CURR:
QP::QS::rxPriv_.var.obj.recId =
static_cast&lt;std::uint8_t&gt;(QP::QS_RX_QUERY_CURR);
tran_(WAIT4_QUERY_KIND);
break;
case QP::QS_RX_EVENT:
tran_(WAIT4_EVT_PRIO);
break;
#ifdef Q_UTEST
case QP::QS_RX_TEST_SETUP:
tran_(WAIT4_TEST_SETUP_FRAME);
break;
case QP::QS_RX_TEST_TEARDOWN:
tran_(WAIT4_TEST_TEARDOWN_FRAME);
break;
case QP::QS_RX_TEST_CONTINUE:
tran_(WAIT4_TEST_CONTINUE_FRAME);
break;
case QP::QS_RX_TEST_PROBE:
if (QP::QS::tstPriv_.tpNum
&lt; static_cast&lt;std::uint8_t&gt;(
(sizeof(QP::QS::tstPriv_.tpBuf)
/ sizeof(QP::QS::tstPriv_.tpBuf[0]))))
{
QP::QS::rxPriv_.var.tp.data = 0U;
QP::QS::rxPriv_.var.tp.idx = 0U;
tran_(WAIT4_TEST_PROBE_DATA);
}
else { // the # Test-Probes exceeded
rxReportError_(
static_cast&lt;std::uint8_t&gt;(QP::QS_RX_TEST_PROBE));
tran_(ERROR_STATE);
}
break;
#endif // Q_UTEST
default:
rxReportError_(0x43U);
tran_(ERROR_STATE);
break;
}
break;
}
case WAIT4_INFO_FRAME: {
// keep ignoring the data until a frame is collected
break;
}
case WAIT4_CMD_ID: {
QP::QS::rxPriv_.var.cmd.cmdId = b;
QP::QS::rxPriv_.var.cmd.idx = 0U;
QP::QS::rxPriv_.var.cmd.param1 = 0U;
QP::QS::rxPriv_.var.cmd.param2 = 0U;
QP::QS::rxPriv_.var.cmd.param3 = 0U;
tran_(WAIT4_CMD_PARAM1);
break;
}
case WAIT4_CMD_PARAM1: {
QP::QS::rxPriv_.var.cmd.param1 |=
(static_cast&lt;std::uint32_t&gt;(b) &lt;&lt; QP::QS::rxPriv_.var.cmd.idx);
QP::QS::rxPriv_.var.cmd.idx += 8U;
if (QP::QS::rxPriv_.var.cmd.idx == (8U * 4U)) {
QP::QS::rxPriv_.var.cmd.idx = 0U;
tran_(WAIT4_CMD_PARAM2);
}
break;
}
case WAIT4_CMD_PARAM2: {
QP::QS::rxPriv_.var.cmd.param2 |=
static_cast&lt;std::uint32_t&gt;(b) &lt;&lt; QP::QS::rxPriv_.var.cmd.idx;
QP::QS::rxPriv_.var.cmd.idx += 8U;
if (QP::QS::rxPriv_.var.cmd.idx == (8U * 4U)) {
QP::QS::rxPriv_.var.cmd.idx = 0U;
tran_(WAIT4_CMD_PARAM3);
}
break;
}
case WAIT4_CMD_PARAM3: {
QP::QS::rxPriv_.var.cmd.param3 |=
static_cast&lt;std::uint32_t&gt;(b) &lt;&lt; QP::QS::rxPriv_.var.cmd.idx;
QP::QS::rxPriv_.var.cmd.idx += 8U;
if (QP::QS::rxPriv_.var.cmd.idx == (8U * 4U)) {
QP::QS::rxPriv_.var.cmd.idx = 0U;
tran_(WAIT4_CMD_FRAME);
}
break;
}
case WAIT4_CMD_FRAME: {
// keep ignoring the data until a frame is collected
break;
}
case WAIT4_RESET_FRAME: {
// keep ignoring the data until a frame is collected
break;
}
case WAIT4_TICK_RATE: {
QP::QS::rxPriv_.var.tick.rate = static_cast&lt;std::uint_fast8_t&gt;(b);
tran_(WAIT4_TICK_FRAME);
break;
}
case WAIT4_TICK_FRAME: {
// keep ignoring the data until a frame is collected
break;
}
case WAIT4_PEEK_OFFS: {
if (QP::QS::rxPriv_.var.peek.idx == 0U) {
QP::QS::rxPriv_.var.peek.offs = static_cast&lt;std::uint16_t&gt;(b);
QP::QS::rxPriv_.var.peek.idx += 8U;
}
else {
QP::QS::rxPriv_.var.peek.offs |= static_cast&lt;std::uint16_t&gt;(
static_cast&lt;std::uint16_t&gt;(b) &lt;&lt; 8U);
tran_(WAIT4_PEEK_SIZE);
}
break;
}
case WAIT4_PEEK_SIZE: {
if ((b == 1U) || (b == 2U) || (b == 4U)) {
QP::QS::rxPriv_.var.peek.size = b;
tran_(WAIT4_PEEK_NUM);
}
else {
rxReportError_(static_cast&lt;std::uint8_t&gt;(QP::QS_RX_PEEK));
tran_(ERROR_STATE);
}
break;
}
case WAIT4_PEEK_NUM: {
QP::QS::rxPriv_.var.peek.num = b;
tran_(WAIT4_PEEK_FRAME);
break;
}
case WAIT4_PEEK_FRAME: {
// keep ignoring the data until a frame is collected
break;
}
case WAIT4_POKE_OFFS: {
if (QP::QS::rxPriv_.var.poke.idx == 0U) {
QP::QS::rxPriv_.var.poke.offs = static_cast&lt;std::uint16_t&gt;(b);
QP::QS::rxPriv_.var.poke.idx = 1U;
}
else {
QP::QS::rxPriv_.var.poke.offs |= static_cast&lt;std::uint16_t&gt;(
static_cast&lt;std::uint16_t&gt;(b) &lt;&lt; 8U);
tran_(WAIT4_POKE_SIZE);
}
break;
}
case WAIT4_POKE_SIZE: {
if ((b == 1U) || (b == 2U) || (b == 4U)) {
QP::QS::rxPriv_.var.poke.size = b;
tran_(WAIT4_POKE_NUM);
}
else {
rxReportError_((QP::QS::rxPriv_.var.poke.fill != 0U)
? static_cast&lt;std::uint8_t&gt;(QP::QS_RX_FILL)
: static_cast&lt;std::uint8_t&gt;(QP::QS_RX_POKE));
tran_(ERROR_STATE);
}
break;
}
case WAIT4_POKE_NUM: {
if (b &gt; 0U) {
QP::QS::rxPriv_.var.poke.num = b;
QP::QS::rxPriv_.var.poke.data = 0U;
QP::QS::rxPriv_.var.poke.idx = 0U;
tran_((QP::QS::rxPriv_.var.poke.fill != 0U)
? WAIT4_FILL_DATA
: WAIT4_POKE_DATA);
}
else {
rxReportError_((QP::QS::rxPriv_.var.poke.fill != 0U)
? static_cast&lt;std::uint8_t&gt;(QP::QS_RX_FILL)
: static_cast&lt;std::uint8_t&gt;(QP::QS_RX_POKE));
tran_(ERROR_STATE);
}
break;
}
case WAIT4_FILL_DATA: {
QP::QS::rxPriv_.var.poke.data |=
static_cast&lt;std::uint32_t&gt;(b) &lt;&lt; QP::QS::rxPriv_.var.poke.idx;
QP::QS::rxPriv_.var.poke.idx += 8U;
if ((QP::QS::rxPriv_.var.poke.idx &gt;&gt; 3U) == QP::QS::rxPriv_.var.poke.size) {
tran_(WAIT4_FILL_FRAME);
}
break;
}
case WAIT4_POKE_DATA: {
QP::QS::rxPriv_.var.poke.data |=
static_cast&lt;std::uint32_t&gt;(b) &lt;&lt; QP::QS::rxPriv_.var.poke.idx;
QP::QS::rxPriv_.var.poke.idx += 8U;
if ((QP::QS::rxPriv_.var.poke.idx &gt;&gt; 3U) == QP::QS::rxPriv_.var.poke.size) {
rxPoke_();
--QP::QS::rxPriv_.var.poke.num;
if (QP::QS::rxPriv_.var.poke.num == 0U) {
tran_(WAIT4_POKE_FRAME);
}
}
break;
}
case WAIT4_FILL_FRAME: {
// keep ignoring the data until a frame is collected
break;
}
case WAIT4_POKE_FRAME: {
// keep ignoring the data until a frame is collected
break;
}
case WAIT4_FILTER_LEN: {
if (b == static_cast&lt;std::uint8_t&gt;(sizeof(QP::QS::rxPriv_.var.flt.data))) {
QP::QS::rxPriv_.var.flt.idx = 0U;
tran_(WAIT4_FILTER_DATA);
}
else {
rxReportError_(QP::QS::rxPriv_.var.flt.recId);
tran_(ERROR_STATE);
}
break;
}
case WAIT4_FILTER_DATA: {
QP::QS::rxPriv_.var.flt.data[QP::QS::rxPriv_.var.flt.idx] = b;
++QP::QS::rxPriv_.var.flt.idx;
if (QP::QS::rxPriv_.var.flt.idx == sizeof(QP::QS::rxPriv_.var.flt.data)) {
tran_(WAIT4_FILTER_FRAME);
}
break;
}
case WAIT4_FILTER_FRAME: {
// keep ignoring the data until a frame is collected
break;
}
case WAIT4_OBJ_KIND: {
if (b &lt;= static_cast&lt;std::uint8_t&gt;(QP::QS::SM_AO_OBJ)) {
QP::QS::rxPriv_.var.obj.kind = b;
QP::QS::rxPriv_.var.obj.addr = 0U;
QP::QS::rxPriv_.var.obj.idx = 0U;
tran_(WAIT4_OBJ_ADDR);
}
else {
rxReportError_(QP::QS::rxPriv_.var.obj.recId);
tran_(ERROR_STATE);
}
break;
}
case WAIT4_OBJ_ADDR: {
QP::QS::rxPriv_.var.obj.addr |=
static_cast&lt;QP::QSObj&gt;(b) &lt;&lt; QP::QS::rxPriv_.var.obj.idx;
QP::QS::rxPriv_.var.obj.idx += 8U;
if (QP::QS::rxPriv_.var.obj.idx
== (8U * static_cast&lt;unsigned&gt;(QS_OBJ_PTR_SIZE)))
{
tran_(WAIT4_OBJ_FRAME);
}
break;
}
case WAIT4_OBJ_FRAME: {
// keep ignoring the data until a frame is collected
break;
}
case WAIT4_QUERY_KIND: {
if (b &lt; static_cast&lt;std::uint8_t&gt;(QP::QS::MAX_OBJ)) {
QP::QS::rxPriv_.var.obj.kind = b;
tran_(WAIT4_QUERY_FRAME);
}
else {
rxReportError_(QP::QS::rxPriv_.var.obj.recId);
tran_(ERROR_STATE);
}
break;
}
case WAIT4_QUERY_FRAME: {
// keep ignoring the data until a frame is collected
break;
}
case WAIT4_EVT_PRIO: {
QP::QS::rxPriv_.var.evt.prio = b;
QP::QS::rxPriv_.var.evt.sig = 0U;
QP::QS::rxPriv_.var.evt.idx = 0U;
tran_(WAIT4_EVT_SIG);
break;
}
case WAIT4_EVT_SIG: {
QP::QS::rxPriv_.var.evt.sig |= static_cast&lt;QP::QSignal&gt;(
static_cast&lt;std::uint32_t&gt;(b) &lt;&lt; QP::QS::rxPriv_.var.evt.idx);
QP::QS::rxPriv_.var.evt.idx += 8U;
if (QP::QS::rxPriv_.var.evt.idx
== (8U *static_cast&lt;unsigned&gt;(Q_SIGNAL_SIZE)))
{
QP::QS::rxPriv_.var.evt.len = 0U;
QP::QS::rxPriv_.var.evt.idx = 0U;
tran_(WAIT4_EVT_LEN);
}
break;
}
case WAIT4_EVT_LEN: {
QP::QS::rxPriv_.var.evt.len |= static_cast&lt;std::uint16_t&gt;(
static_cast&lt;unsigned&gt;(b) &lt;&lt; QP::QS::rxPriv_.var.evt.idx);
QP::QS::rxPriv_.var.evt.idx += 8U;
if (QP::QS::rxPriv_.var.evt.idx == (8U * 2U)) {
if ((QP::QS::rxPriv_.var.evt.len + sizeof(QP::QEvt))
&lt;= QP::QF::poolGetMaxBlockSize())
{
// report Ack before generating any other QS records
rxReportAck_(QP::QS_RX_EVENT);
QP::QS::rxPriv_.var.evt.e = QP::QF::newX_(
(static_cast&lt;std::uint_fast16_t&gt;(QP::QS::rxPriv_.var.evt.len)
+ sizeof(QP::QEvt)),
0U, // margin
static_cast&lt;enum_t&gt;(QP::QS::rxPriv_.var.evt.sig));
// event allocated?
if (QP::QS::rxPriv_.var.evt.e != nullptr) {
QP::QS::rxPriv_.var.evt.p =
reinterpret_cast&lt;std::uint8_t *&gt;(QP::QS::rxPriv_.var.evt.e);
QP::QS::rxPriv_.var.evt.p = &amp;QP::QS::rxPriv_.var.evt.p[sizeof(QP::QEvt)];
if (QP::QS::rxPriv_.var.evt.len &gt; 0U) {
tran_(WAIT4_EVT_PAR);
}
else {
tran_(WAIT4_EVT_FRAME);
}
}
else {
rxReportError_(
static_cast&lt;std::uint8_t&gt;(QP::QS_RX_EVENT));
tran_(ERROR_STATE);
}
}
else {
rxReportError_(
static_cast&lt;std::uint8_t&gt;(QP::QS_RX_EVENT));
tran_(ERROR_STATE);
}
}
break;
}
case WAIT4_EVT_PAR: { // event parameters
*QP::QS::rxPriv_.var.evt.p = b;
++QP::QS::rxPriv_.var.evt.p;
--QP::QS::rxPriv_.var.evt.len;
if (QP::QS::rxPriv_.var.evt.len == 0U) {
tran_(WAIT4_EVT_FRAME);
}
break;
}
case WAIT4_EVT_FRAME: {
// keep ignoring the data until a frame is collected
break;
}
#ifdef Q_UTEST
case WAIT4_TEST_SETUP_FRAME: {
// keep ignoring the data until a frame is collected
break;
}
case WAIT4_TEST_TEARDOWN_FRAME: {
// keep ignoring the data until a frame is collected
break;
}
case WAIT4_TEST_CONTINUE_FRAME: {
// keep ignoring the data until a frame is collected
break;
}
case WAIT4_TEST_PROBE_DATA: {
QP::QS::rxPriv_.var.tp.data |=
(static_cast&lt;QP::QSFun&gt;(b) &lt;&lt; QP::QS::rxPriv_.var.tp.idx);
QP::QS::rxPriv_.var.tp.idx += 8U;
if (QP::QS::rxPriv_.var.tp.idx == (8U * sizeof(std::uint32_t))) {
QP::QS::rxPriv_.var.tp.addr = 0U;
QP::QS::rxPriv_.var.tp.idx = 0U;
tran_(WAIT4_TEST_PROBE_ADDR);
}
break;
}
case WAIT4_TEST_PROBE_ADDR: {
QP::QS::rxPriv_.var.tp.addr |=
(static_cast&lt;std::uint32_t&gt;(b) &lt;&lt; QP::QS::rxPriv_.var.tp.idx);
QP::QS::rxPriv_.var.tp.idx += 8U;
if (QP::QS::rxPriv_.var.tp.idx
== (8U * static_cast&lt;unsigned&gt;(QS_FUN_PTR_SIZE)))
{
tran_(WAIT4_TEST_PROBE_FRAME);
}
break;
}
case WAIT4_TEST_PROBE_FRAME: {
// keep ignoring the data until a frame is collected
break;
}
#endif // Q_UTEST
case ERROR_STATE: {
// keep ignoring the data until a good frame is collected
break;
}
default: { // unexpected or unimplemented state
rxReportError_(0x45U);
tran_(ERROR_STATE);
break;
}
}
}
//............................................................................
void rxHandleGoodFrame_(std::uint8_t const state) {
std::uint8_t i;
std::uint8_t *ptr;
QS_CRIT_STAT
switch (state) {
case WAIT4_INFO_FRAME: {
// no need to report Ack or Done
QS_CRIT_ENTRY();
QS_MEM_SYS();
QP::QS::target_info_pre_(0U); // send only Target info
QS_MEM_APP();
QS_CRIT_EXIT();
break;
}
case WAIT4_RESET_FRAME: {
// no need to report Ack or Done, because Target resets
QP::QS::onReset(); // reset the Target
break;
}
case WAIT4_CMD_PARAM1: // intentionally fall-through
case WAIT4_CMD_PARAM2: // intentionally fall-through
case WAIT4_CMD_PARAM3: // intentionally fall-through
case WAIT4_CMD_FRAME: {
rxReportAck_(QP::QS_RX_COMMAND);
QP::QS::onCommand(QP::QS::rxPriv_.var.cmd.cmdId, QP::QS::rxPriv_.var.cmd.param1,
QP::QS::rxPriv_.var.cmd.param2, QP::QS::rxPriv_.var.cmd.param3);
#ifdef Q_UTEST
#if Q_UTEST != 0
QP::QS::processTestEvts_(); // process all events produced
#endif // Q_UTEST != 0
#endif // Q_UTEST
rxReportDone_(QP::QS_RX_COMMAND);
break;
}
case WAIT4_TICK_FRAME: {
rxReportAck_(QP::QS_RX_TICK);
#ifdef Q_UTEST
QP::QTimeEvt::tick1_(
static_cast&lt;std::uint_fast8_t&gt;(QP::QS::rxPriv_.var.tick.rate),
&amp;QP::QS::rxPriv_);
#if Q_UTEST != 0
QP::QS::processTestEvts_(); // process all events produced
#endif // Q_UTEST != 0
#else
QP::QTimeEvt::tick(
static_cast&lt;std::uint_fast8_t&gt;(QP::QS::rxPriv_.var.tick.rate),
&amp;QP::QS::rxPriv_);
#endif // Q_UTEST
rxReportDone_(QP::QS_RX_TICK);
break;
}
case WAIT4_PEEK_FRAME: {
// no need to report Ack or Done
QS_CRIT_ENTRY();
QS_MEM_SYS();
QP::QS::beginRec_(static_cast&lt;std::uint_fast8_t&gt;(
QP::QS_PEEK_DATA));
ptr = static_cast&lt;std::uint8_t*&gt;(
QP::QS::rxPriv_.currObj[QP::QS::AP_OBJ]);
ptr = &amp;ptr[QP::QS::rxPriv_.var.peek.offs];
QS_TIME_PRE_(); // timestamp
QS_U16_PRE_(QP::QS::rxPriv_.var.peek.offs); // data offset
QS_U8_PRE_(QP::QS::rxPriv_.var.peek.size); // data size
QS_U8_PRE_(QP::QS::rxPriv_.var.peek.num); // number of data items
for (i = 0U; i &lt; QP::QS::rxPriv_.var.peek.num; ++i) {
switch (QP::QS::rxPriv_.var.peek.size) {
case 1:
QS_U8_PRE_(ptr[i]);
break;
case 2:
QS_U16_PRE_(
reinterpret_cast&lt;std::uint16_t*&gt;(ptr)[i]);
break;
case 4:
QS_U32_PRE_(
reinterpret_cast&lt;std::uint32_t*&gt;(ptr)[i]);
break;
default:
// intentionally empty
break;
}
}
QP::QS::endRec_();
QS_MEM_APP();
QS_CRIT_EXIT();
QS_REC_DONE(); // user callback (if defined)
break;
}
case WAIT4_POKE_DATA: {
// received less than expected poke data items
rxReportError_(static_cast&lt;std::uint8_t&gt;(QP::QS_RX_POKE));
break;
}
case WAIT4_POKE_FRAME: {
rxReportAck_(QP::QS_RX_POKE);
// no need to report done
break;
}
case WAIT4_FILL_FRAME: {
rxReportAck_(QP::QS_RX_FILL);
ptr = static_cast&lt;std::uint8_t *&gt;(
QP::QS::rxPriv_.currObj[QP::QS::AP_OBJ]);
ptr = &amp;ptr[QP::QS::rxPriv_.var.poke.offs];
for (i = 0U; i &lt; QP::QS::rxPriv_.var.poke.num; ++i) {
switch (QP::QS::rxPriv_.var.poke.size) {
case 1:
ptr[i] =
static_cast&lt;std::uint8_t&gt;(QP::QS::rxPriv_.var.poke.data);
break;
case 2:
reinterpret_cast&lt;std::uint16_t *&gt;(ptr)[i] =
static_cast&lt;std::uint16_t&gt;(QP::QS::rxPriv_.var.poke.data);
break;
case 4:
reinterpret_cast&lt;std::uint32_t *&gt;(ptr)[i] =
QP::QS::rxPriv_.var.poke.data;
break;
default:
// intentionally empty
break;
}
}
break;
}
case WAIT4_FILTER_FRAME: {
rxReportAck_(static_cast&lt;enum QP::QSpyRxRecords&gt;(
QP::QS::rxPriv_.var.flt.recId));
// apply the received filters
if (QP::QS::rxPriv_.var.flt.recId
== static_cast&lt;std::uint8_t&gt;(QP::QS_RX_GLB_FILTER))
{
for (i = 0U;
i &lt; static_cast&lt;std::uint8_t&gt;(sizeof(QP::QS::filt_.glb));
++i)
{
QP::QS::filt_.glb[i] = QP::QS::rxPriv_.var.flt.data[i];
}
// leave the &quot;not maskable&quot; filters enabled,
// see qs.hpp, Miscellaneous QS records (not maskable)
QP::QS::filt_.glb[0] |= 0x01U;
QP::QS::filt_.glb[7] |= 0xFCU;
QP::QS::filt_.glb[8] |= 0x7FU;
// never enable the last 3 records (0x7D, 0x7E, 0x7F)
QP::QS::filt_.glb[15] &amp;= 0x1FU;
}
else if (QP::QS::rxPriv_.var.flt.recId
== static_cast&lt;std::uint8_t&gt;(QP::QS_RX_LOC_FILTER))
{
for (i = 0U; i &lt; Q_DIM(QP::QS::filt_.loc); ++i) {
QP::QS::filt_.loc[i] = QP::QS::rxPriv_.var.flt.data[i];
}
// leave QS_ID == 0 always on
QP::QS::filt_.loc[0] |= 0x01U;
}
else {
rxReportError_(QP::QS::rxPriv_.var.flt.recId);
}
// no need to report Done
break;
}
case WAIT4_OBJ_FRAME: {
i = QP::QS::rxPriv_.var.obj.kind;
if (i &lt; static_cast&lt;std::uint8_t&gt;(QP::QS::MAX_OBJ)) {
if (QP::QS::rxPriv_.var.obj.recId
== static_cast&lt;std::uint8_t&gt;(QP::QS_RX_CURR_OBJ))
{
QP::QS::rxPriv_.currObj[i] =
reinterpret_cast&lt;void *&gt;(QP::QS::rxPriv_.var.obj.addr);
rxReportAck_(QP::QS_RX_CURR_OBJ);
}
else if (QP::QS::rxPriv_.var.obj.recId
== static_cast&lt;std::uint8_t&gt;(QP::QS_RX_AO_FILTER))
{
if (QP::QS::rxPriv_.var.obj.addr != 0U) {
std::int_fast16_t const filter =
static_cast&lt;std::int_fast16_t&gt;(
reinterpret_cast&lt;QP::QActive *&gt;(
QP::QS::rxPriv_.var.obj.addr)-&gt;getPrio());
QP::QS::locFilter_((i == 0)
? filter
:-filter);
rxReportAck_(QP::QS_RX_AO_FILTER);
}
else {
rxReportError_(static_cast&lt;enum_t&gt;(
QP::QS_RX_AO_FILTER));
}
}
else {
rxReportError_(QP::QS::rxPriv_.var.obj.recId);
}
}
// both SM and AO
else if (i == static_cast&lt;std::uint8_t&gt;(QP::QS::SM_AO_OBJ)) {
if (QP::QS::rxPriv_.var.obj.recId
== static_cast&lt;std::uint8_t&gt;(QP::QS_RX_CURR_OBJ))
{
QP::QS::rxPriv_.currObj[QP::QS::SM_OBJ]
= reinterpret_cast&lt;void *&gt;(QP::QS::rxPriv_.var.obj.addr);
QP::QS::rxPriv_.currObj[QP::QS::AO_OBJ]
= reinterpret_cast&lt;void *&gt;(QP::QS::rxPriv_.var.obj.addr);
}
rxReportAck_(
static_cast&lt;enum QP::QSpyRxRecords&gt;(QP::QS::rxPriv_.var.obj.recId));
}
else {
rxReportError_(QP::QS::rxPriv_.var.obj.recId);
}
break;
}
case WAIT4_QUERY_FRAME: {
queryCurrObj_(QP::QS::rxPriv_.var.obj.kind);
break;
}
case WAIT4_EVT_FRAME: {
// NOTE: Ack was already reported in the WAIT4_EVT_LEN state
#ifdef Q_UTEST
QP::QS::onTestEvt(QP::QS::rxPriv_.var.evt.e); // &quot;massage&quot; the event
#endif // Q_UTEST
// use 'i' as status, 0 == success,no-recycle
i = 0U;
if (QP::QS::rxPriv_.var.evt.prio == 0U) { // publish
QP::QActive::publish_(QP::QS::rxPriv_.var.evt.e, &amp;QP::QS::rxPriv_, 0U);
}
else if (QP::QS::rxPriv_.var.evt.prio &lt; QF_MAX_ACTIVE) {
if (!QP::QActive::registry_[QP::QS::rxPriv_.var.evt.prio]-&gt;POST_X(
QP::QS::rxPriv_.var.evt.e,
0U, // margin
&amp;QP::QS::rxPriv_))
{
// failed QACTIVE_POST() recycles the event
i = 0x80U; // failure status, no recycle
}
}
else if (QP::QS::rxPriv_.var.evt.prio == 255U) {
// dispatch to the current SM object
if (QP::QS::rxPriv_.currObj[QP::QS::SM_OBJ] != nullptr) {
// increment the ref-ctr to simulate the situation
// when the event is just retrieved from a queue.
// This is expected for the following QF::gc() call.
QP::QEvt_refCtr_inc_(QP::QS::rxPriv_.var.evt.e);
static_cast&lt;QP::QAsm *&gt;(
QP::QS::rxPriv_.currObj[QP::QS::SM_OBJ])
-&gt;dispatch(QP::QS::rxPriv_.var.evt.e, 0U);
i = 0x01U; // success, recycle
}
else {
i = 0x81U; // failure, recycle
}
}
else if (QP::QS::rxPriv_.var.evt.prio == 254U) {
// init the current SM object&quot;
if (QP::QS::rxPriv_.currObj[QP::QS::SM_OBJ] != nullptr) {
// increment the ref-ctr to simulate the situation
// when the event is just retrieved from a queue.
// This is expected for the following QF::gc() call.
QP::QEvt_refCtr_inc_(QP::QS::rxPriv_.var.evt.e);
static_cast&lt;QP::QAsm *&gt;(
QP::QS::rxPriv_.currObj[QP::QS::SM_OBJ])
-&gt;init(QP::QS::rxPriv_.var.evt.e, 0U);
i = 0x01U; // success, recycle
}
else {
i = 0x81U; // failure, recycle
}
}
else if (QP::QS::rxPriv_.var.evt.prio == 253U) {
// post to the current AO
if (QP::QS::rxPriv_.currObj[QP::QS::AO_OBJ] != nullptr) {
if (!static_cast&lt;QP::QActive *&gt;(
QP::QS::rxPriv_.currObj[QP::QS::AO_OBJ])-&gt;POST_X(
QP::QS::rxPriv_.var.evt.e,
0U, // margin
&amp;QP::QS::rxPriv_))
{
// failed QACTIVE_POST() recycles the event
i = 0x80U; // failure, no recycle
}
}
else {
i = 0x81U; // failure, recycle
}
}
else {
i = 0x81U; // failure, recycle
}
#if (QF_MAX_EPOOL &gt; 0U)
// recycle needed?
if ((i &amp; 1U) != 0U) {
QP::QF::gc(QP::QS::rxPriv_.var.evt.e);
}
#endif
// failure?
if ((i &amp; 0x80U) != 0U) {
rxReportError_(static_cast&lt;std::uint8_t&gt;(QP::QS_RX_EVENT));
}
else {
#ifdef Q_UTEST
#if Q_UTEST != 0
QP::QS::processTestEvts_(); // process all events produced
#endif // Q_UTEST != 0
#endif // Q_UTEST
rxReportDone_(QP::QS_RX_EVENT);
}
break;
}
#ifdef Q_UTEST
case WAIT4_TEST_SETUP_FRAME: {
rxReportAck_(QP::QS_RX_TEST_SETUP);
QP::QS::tstPriv_.tpNum = 0U; // clear Test-Probes
QP::QS::tstPriv_.testTime = 0U; //clear time tick
// don't clear current objects
QP::QS::onTestSetup(); // application-specific test setup
// no need to report Done
break;
}
case WAIT4_TEST_TEARDOWN_FRAME: {
rxReportAck_(QP::QS_RX_TEST_TEARDOWN);
QP::QS::onTestTeardown(); // application-specific test teardown
// no need to report Done
break;
}
case WAIT4_TEST_CONTINUE_FRAME: {
rxReportAck_(QP::QS_RX_TEST_CONTINUE);
QP::QS::rxPriv_.inTestLoop = false; // exit the QUTest loop
// no need to report Done
break;
}
case WAIT4_TEST_PROBE_FRAME: {
rxReportAck_(QP::QS_RX_TEST_PROBE);
Q_ASSERT_INCRIT(815,
QP::QS::tstPriv_.tpNum
&lt; (sizeof(QP::QS::tstPriv_.tpBuf)
/ sizeof(QP::QS::tstPriv_.tpBuf[0])));
QP::QS::tstPriv_.tpBuf[QP::QS::tstPriv_.tpNum] = QP::QS::rxPriv_.var.tp;
++QP::QS::tstPriv_.tpNum;
// no need to report Done
break;
}
#endif // Q_UTEST
case ERROR_STATE: {
// keep ignoring all bytes until new frame
break;
}
default: {
rxReportError_(0x47U);
break;
}
}
}
//............................................................................
static void rxHandleBadFrame_(std::uint8_t const state) noexcept {
rxReportError_(0x50U); // error for all bad frames
switch (state) {
case WAIT4_EVT_FRAME: {
QS_CRIT_STAT
QS_CRIT_ENTRY();
Q_ASSERT_INCRIT(910, QP::QS::rxPriv_.var.evt.e != nullptr);
QS_CRIT_EXIT();
#if (QF_MAX_EPOOL &gt; 0U)
QP::QF::gc(QP::QS::rxPriv_.var.evt.e); // don't leak allocated evt
#endif
break;
}
default: {
// intentionally empty
break;
}
}
}
//............................................................................
static void rxReportAck_(enum QP::QSpyRxRecords const recId) noexcept {
QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
QP::QS::beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QP::QS_RX_STATUS));
QS_U8_PRE_(recId); // record ID
QP::QS::endRec_();
QS_MEM_APP();
QS_CRIT_EXIT();
QS_REC_DONE(); // user callback (if defined)
}
//............................................................................
static void rxReportError_(std::uint8_t const code) noexcept {
QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
QP::QS::beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QP::QS_RX_STATUS));
QS_U8_PRE_(0x80U | code); // error code
QP::QS::endRec_();
QS_MEM_APP();
QS_CRIT_EXIT();
QS_REC_DONE(); // user callback (if defined)
}
//............................................................................
static void rxReportDone_(enum QP::QSpyRxRecords const recId) noexcept {
QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
QP::QS::beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QP::QS_TARGET_DONE));
QS_TIME_PRE_(); // timestamp
QS_U8_PRE_(recId); // record ID
QP::QS::endRec_();
QS_MEM_APP();
QS_CRIT_EXIT();
QS_REC_DONE(); // user callback (if defined)
}
//............................................................................
static void queryCurrObj_(std::uint8_t obj_kind) noexcept {
QS_CRIT_STAT
QS_CRIT_ENTRY();
Q_REQUIRE_INCRIT(800, obj_kind &lt; Q_DIM(QP::QS::rxPriv_.currObj));
QS_CRIT_EXIT();
if (QP::QS::rxPriv_.currObj[obj_kind] != nullptr) {
QS_CRIT_ENTRY();
QS_MEM_SYS();
QP::QS::beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QP::QS_QUERY_DATA));
QS_TIME_PRE_(); // timestamp
QS_U8_PRE_(obj_kind); // object kind
QS_OBJ_PRE_(QP::QS::rxPriv_.currObj[obj_kind]); // object pointer
switch (obj_kind) {
case QP::QS::SM_OBJ: // intentionally fall through
case QP::QS::AO_OBJ:
QS_FUN_PRE_(reinterpret_cast&lt;QP::QHsm *&gt;(
QP::QS::rxPriv_.currObj[obj_kind])-&gt;getStateHandler());
break;
case QP::QS::MP_OBJ:
QS_MPC_PRE_(reinterpret_cast&lt;QP::QMPool *&gt;(
QP::QS::rxPriv_.currObj[obj_kind])-&gt;getNFree());
QS_MPC_PRE_(reinterpret_cast&lt;QP::QMPool *&gt;(
QP::QS::rxPriv_.currObj[obj_kind])-&gt;getNMin());
break;
case QP::QS::EQ_OBJ:
QS_EQC_PRE_(reinterpret_cast&lt;QP::QEQueue *&gt;(
QP::QS::rxPriv_.currObj[obj_kind])-&gt;getNFree());
QS_EQC_PRE_(reinterpret_cast&lt;QP::QEQueue *&gt;(
QP::QS::rxPriv_.currObj[obj_kind])-&gt;getNMin());
break;
case QP::QS::TE_OBJ:
QS_OBJ_PRE_(reinterpret_cast&lt;QP::QTimeEvt *&gt;(
QP::QS::rxPriv_.currObj[obj_kind])-&gt;getAct());
QS_TEC_PRE_(reinterpret_cast&lt;QP::QTimeEvt *&gt;(
QP::QS::rxPriv_.currObj[obj_kind])-&gt;getCtr());
QS_TEC_PRE_(reinterpret_cast&lt;QP::QTimeEvt *&gt;(
QP::QS::rxPriv_.currObj[obj_kind])-&gt;getInterval());
QS_SIG_PRE_(reinterpret_cast&lt;QP::QTimeEvt *&gt;(
QP::QS::rxPriv_.currObj[obj_kind])-&gt;sig);
QS_U8_PRE_ (reinterpret_cast&lt;QP::QTimeEvt *&gt;(
QP::QS::rxPriv_.currObj[obj_kind])-&gt;refCtr_);
break;
default:
// intentionally empty
break;
}
QP::QS::endRec_();
QS_MEM_APP();
QS_CRIT_EXIT();
QS_REC_DONE(); // user callback (if defined)
}
else {
rxReportError_(static_cast&lt;std::uint8_t&gt;(QP::QS_RX_AO_FILTER));
}
}
//............................................................................
static void rxPoke_() noexcept {
std::uint8_t * ptr =
static_cast&lt;std::uint8_t *&gt;(QP::QS::rxPriv_.currObj[QP::QS::AP_OBJ]);
ptr = &amp;ptr[QP::QS::rxPriv_.var.poke.offs];
switch (QP::QS::rxPriv_.var.poke.size) {
case 1:
*ptr = static_cast&lt;std::uint8_t&gt;(QP::QS::rxPriv_.var.poke.data);
break;
case 2:
*reinterpret_cast&lt;std::uint16_t *&gt;(ptr)
= static_cast&lt;std::uint16_t&gt;(QP::QS::rxPriv_.var.poke.data);
break;
case 4:
*reinterpret_cast&lt;std::uint32_t *&gt;(ptr) = QP::QS::rxPriv_.var.poke.data;
break;
default:
Q_ERROR_ID(900);
break;
}
QP::QS::rxPriv_.var.poke.data = 0U;
QP::QS::rxPriv_.var.poke.idx = 0U;
QP::QS::rxPriv_.var.poke.offs += static_cast&lt;std::uint16_t&gt;(QP::QS::rxPriv_.var.poke.size);
}
} // unnamed namespace
//! @endcond</text>
</file>
<!--${src::qs::qutest.cpp}-->
<file name="qutest.cpp">
<text>// only build when Q_UTEST is defined
#ifdef Q_UTEST
#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS package-scope internal interface
$define ${QS::QUTest}
//============================================================================
//! @cond INTERNAL
namespace QP {
namespace QS {
TestAttr tstPriv_;
//............................................................................
void test_pause_() {
beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QS_TEST_PAUSED));
endRec_();
onTestLoop();
}
//............................................................................
std::uint32_t getTestProbe_(QSpyFunPtr const api) noexcept {
std::uint32_t data = 0U;
for (std::uint8_t i = 0U; i &lt; tstPriv_.tpNum; ++i) {
if (tstPriv_.tpBuf[i].addr == reinterpret_cast&lt;QSFun&gt;(api)) {
data = tstPriv_.tpBuf[i].data;
QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS::beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QS_TEST_PROBE_GET));
QS_TIME_PRE_(); // timestamp
QS_FUN_PRE_(api); // the calling API
QS_U32_PRE_(data); // the Test-Probe data
QS::endRec_();
QS_REC_DONE(); // user callback (if defined)
--tstPriv_.tpNum; // one less Test-Probe
// move all remaining entries in the buffer up by one
for (std::uint8_t j = i; j &lt; tstPriv_.tpNum; ++j) {
tstPriv_.tpBuf[j] = tstPriv_.tpBuf[j + 1U];
}
QS_MEM_APP();
QS_CRIT_EXIT();
break; // we are done (Test-Probe retrieved)
}
}
return data;
}
//............................................................................
QSTimeCtr onGetTime() {
return (++tstPriv_.testTime);
}
} // namespace QS
} // namespace QP
//............................................................................
extern &quot;C&quot; {
Q_NORETURN Q_onError(
char const * const module,
int_t const id)
{
// NOTE: called in a critical section
QP::QS::beginRec_(static_cast&lt;std::uint_fast8_t&gt;(QP::QS_ASSERT_FAIL));
QS_TIME_PRE_();
QS_U16_PRE_(id);
QS_STR_PRE_((module != nullptr) ? module : &quot;?&quot;);
QP::QS::endRec_();
QP::QS::onFlush(); // flush the assertion record to the host
QP::QS::onCleanup(); // cleanup after the failure
QP::QS::onReset(); // reset the target to prevent it from continuing
for (;;) { // onReset() should not return, but to ensure no-return...
}
}
} // extern &quot;C&quot;
//! @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. In that case, the build process
// can define Q_UTEST=0 to exclude the QP-stub from the build.
#if Q_UTEST != 0
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qutest&quot;)
} // unnamed namespace
namespace QP {
namespace QS {
void processTestEvts_() {
QS_TEST_PROBE_DEF(&amp;QS::processTestEvts_)
// return immediately (do nothing) for Test Probe != 0
QS_TEST_PROBE(return;)
while (tstPriv_.readySet.notEmpty()) {
std::uint_fast8_t const p = tstPriv_.readySet.findMax();
QActive * const a = QActive::registry_[p];
QEvt const * const e = a-&gt;get_();
a-&gt;dispatch(e, a-&gt;getPrio());
#if (QF_MAX_EPOOL &gt; 0U)
QF::gc(e);
#endif
if (a-&gt;getEQueue().isEmpty()) { // empty queue?
tstPriv_.readySet.remove(p);
#ifndef Q_UNSAFE
tstPriv_.readySet.update_(&amp;tstPriv_.readySet_dis);
#endif
}
}
}
} // namespace QS
} // namespace QP
$define ${QS::QUTest-stub}
#endif // Q_UTEST != 0
#endif // def Q_UTEST</text>
</file>
<!--${src::qs::qstamp.cpp}-->
<file name="qstamp.cpp">
<text>#include &quot;qstamp.hpp&quot;
namespace QP {
char const BUILD_DATE[12] = __DATE__;
char const BUILD_TIME[9] = __TIME__;
} // namespace QP</text>
</file>
</directory>
</directory>
</model>