QP is an event-driven, RTOS-like, active object framework for microcontrollers, such as mbed. The QP framework provides thread-safe execution of active objects (concurrent state machines) and support both manual and automatic coding of UML statecharts in readable, production-quality C or C++. Automatic code generation of QP code is supported by the free QM modeling tool.

Dependents:   qp_hangman qp_dpp qp_blinky

QP/C++ (Quantum Platform in C++) is a lightweight, open source active object (actor) framework for building responsive and modular real-time embedded applications as systems of asynchronous event-driven active objects (actors). The QP/C++ framework is a member of a larger family consisting of QP/C++, QP/C, and QP-nano frameworks, which are all strictly quality controlled, thoroughly documented, and available under GPLv3 with a special Exception for mbed (see http://www.state-machine.com/licensing/QP-mbed_GPL_Exception.txt).

The behavior of active objects is specified in QP/C++ by means of hierarchical state machines (UML statecharts). The framework supports manual coding of UML state machines in C++ as well as automatic code generation by means of the free QM modeling tool (http://www.state-machine.com/qm).

Please see the "QP/C++ Reference Manual" (http://www.state-machine.com/qpcpp) for more information.

Committer:
QL
Date:
Tue Sep 04 22:20:52 2012 +0000
Revision:
9:ca2e6010d9e2
Parent:
7:bf92d3a6625e
QP/C++ 4.5.02 compatible with QM 2.2.xx

Who changed what in which revision?

UserRevisionLine numberNew contents of line
QL 9:ca2e6010d9e2 1 //////////////////////////////////////////////////////////////////////////////
QL 9:ca2e6010d9e2 2 // Product: QP/C++
QL 9:ca2e6010d9e2 3 // Last Updated for QP ver: 4.5.02 (modified to fit in one file)
QL 9:ca2e6010d9e2 4 // Date of the Last Update: Aug 24, 2012
QL 9:ca2e6010d9e2 5 //
QL 9:ca2e6010d9e2 6 // Q u a n t u m L e a P s
QL 9:ca2e6010d9e2 7 // ---------------------------
QL 9:ca2e6010d9e2 8 // innovating embedded systems
QL 9:ca2e6010d9e2 9 //
QL 9:ca2e6010d9e2 10 // Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved.
QL 9:ca2e6010d9e2 11 //
QL 9:ca2e6010d9e2 12 // This program is open source software: you can redistribute it and/or
QL 9:ca2e6010d9e2 13 // modify it under the terms of the GNU General Public License as published
QL 9:ca2e6010d9e2 14 // by the Free Software Foundation, either version 2 of the License, or
QL 9:ca2e6010d9e2 15 // (at your option) any later version.
QL 9:ca2e6010d9e2 16 //
QL 9:ca2e6010d9e2 17 // Alternatively, this program may be distributed and modified under the
QL 9:ca2e6010d9e2 18 // terms of Quantum Leaps commercial licenses, which expressly supersede
QL 9:ca2e6010d9e2 19 // the GNU General Public License and are specifically designed for
QL 9:ca2e6010d9e2 20 // licensees interested in retaining the proprietary status of their code.
QL 9:ca2e6010d9e2 21 //
QL 9:ca2e6010d9e2 22 // This program is distributed in the hope that it will be useful,
QL 9:ca2e6010d9e2 23 // but WITHOUT ANY WARRANTY; without even the implied warranty of
QL 9:ca2e6010d9e2 24 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
QL 9:ca2e6010d9e2 25 // GNU General Public License for more details.
QL 9:ca2e6010d9e2 26 //
QL 9:ca2e6010d9e2 27 // You should have received a copy of the GNU General Public License
QL 9:ca2e6010d9e2 28 // along with this program. If not, see <http://www.gnu.org/licenses/>.
QL 9:ca2e6010d9e2 29 //
QL 9:ca2e6010d9e2 30 // Contact information:
QL 9:ca2e6010d9e2 31 // Quantum Leaps Web sites: http://www.quantum-leaps.com
QL 9:ca2e6010d9e2 32 // http://www.state-machine.com
QL 9:ca2e6010d9e2 33 // e-mail: info@quantum-leaps.com
QL 9:ca2e6010d9e2 34 //////////////////////////////////////////////////////////////////////////////
QL 9:ca2e6010d9e2 35 #include "qp_port.h" // QP port
QL 9:ca2e6010d9e2 36
QL 9:ca2e6010d9e2 37 // "qep_pkg.h" ===============================================================
QL 9:ca2e6010d9e2 38 QP_BEGIN_
QL 9:ca2e6010d9e2 39
QL 9:ca2e6010d9e2 40 Q_DEFINE_THIS_MODULE("qp")
QL 9:ca2e6010d9e2 41
QL 9:ca2e6010d9e2 42 //////////////////////////////////////////////////////////////////////////////
QL 9:ca2e6010d9e2 43 /// preallocated reserved events
QL 9:ca2e6010d9e2 44 extern QEvt const QEP_reservedEvt_[];
QL 9:ca2e6010d9e2 45
QL 9:ca2e6010d9e2 46 /// empty signal for internal use only
QL 9:ca2e6010d9e2 47 QSignal const QEP_EMPTY_SIG_ = static_cast<QSignal>(0);
QL 9:ca2e6010d9e2 48
QL 9:ca2e6010d9e2 49 /// maximum depth of state nesting (including the top level), must be >= 3
QL 9:ca2e6010d9e2 50 int8_t const QEP_MAX_NEST_DEPTH_ = static_cast<int8_t>(6);
QL 9:ca2e6010d9e2 51
QL 9:ca2e6010d9e2 52 uint8_t const u8_0 = static_cast<uint8_t>(0); ///< \brief constant (uint8_t)0
QL 9:ca2e6010d9e2 53 uint8_t const u8_1 = static_cast<uint8_t>(1); ///< \brief constant (uint8_t)1
QL 9:ca2e6010d9e2 54 int8_t const s8_0 = static_cast<int8_t>(0); ///< \brief constant (int8_t)0
QL 9:ca2e6010d9e2 55 int8_t const s8_1 = static_cast<int8_t>(1); ///< \brief constant (int8_t)1
QL 9:ca2e6010d9e2 56 int8_t const s8_n1 = static_cast<int8_t>(-1); ///< \brief constant (int8_t)-1
QL 9:ca2e6010d9e2 57
QL 9:ca2e6010d9e2 58 QP_END_
QL 9:ca2e6010d9e2 59
QL 9:ca2e6010d9e2 60 /// helper macro to trigger internal event in an HSM
QL 9:ca2e6010d9e2 61 #define QEP_TRIG_(state_, sig_) \
QL 9:ca2e6010d9e2 62 ((*(state_))(this, &QEP_reservedEvt_[sig_]))
QL 9:ca2e6010d9e2 63
QL 9:ca2e6010d9e2 64 /// helper macro to trigger exit action in an HSM
QL 9:ca2e6010d9e2 65 #define QEP_EXIT_(state_) do { \
QL 9:ca2e6010d9e2 66 if (QEP_TRIG_(state_, Q_EXIT_SIG) == Q_RET_HANDLED) { \
QL 9:ca2e6010d9e2 67 QS_BEGIN_(QS_QEP_STATE_EXIT, QS::smObj_, this) \
QL 9:ca2e6010d9e2 68 QS_OBJ_(this); \
QL 9:ca2e6010d9e2 69 QS_FUN_(state_); \
QL 9:ca2e6010d9e2 70 QS_END_() \
QL 9:ca2e6010d9e2 71 } \
QL 9:ca2e6010d9e2 72 } while (false)
QL 9:ca2e6010d9e2 73
QL 9:ca2e6010d9e2 74 /// helper macro to trigger entry action in an HSM
QL 9:ca2e6010d9e2 75 #define QEP_ENTER_(state_) do { \
QL 9:ca2e6010d9e2 76 if (QEP_TRIG_(state_, Q_ENTRY_SIG) == Q_RET_HANDLED) { \
QL 9:ca2e6010d9e2 77 QS_BEGIN_(QS_QEP_STATE_ENTRY, QS::smObj_, this) \
QL 9:ca2e6010d9e2 78 QS_OBJ_(this); \
QL 9:ca2e6010d9e2 79 QS_FUN_(state_); \
QL 9:ca2e6010d9e2 80 QS_END_() \
QL 9:ca2e6010d9e2 81 } \
QL 9:ca2e6010d9e2 82 } while (false)
QL 9:ca2e6010d9e2 83
QL 9:ca2e6010d9e2 84 // "qep.cpp" =================================================================
QL 9:ca2e6010d9e2 85 /// \brief ::QEP_reservedEvt_ definition and QEP::getVersion() implementation.
QL 9:ca2e6010d9e2 86
QL 9:ca2e6010d9e2 87 QP_BEGIN_
QL 9:ca2e6010d9e2 88
QL 9:ca2e6010d9e2 89 // Package-scope objects -----------------------------------------------------
QL 9:ca2e6010d9e2 90 QEvt const QEP_reservedEvt_[] = {
QL 9:ca2e6010d9e2 91 #ifdef Q_EVT_CTOR // Is the QEvt constructor provided?
QL 9:ca2e6010d9e2 92 static_cast<QSignal>(0),
QL 9:ca2e6010d9e2 93 static_cast<QSignal>(1),
QL 9:ca2e6010d9e2 94 static_cast<QSignal>(2),
QL 9:ca2e6010d9e2 95 static_cast<QSignal>(3)
QL 9:ca2e6010d9e2 96 #else // QEvt is a POD (Plain Old Datatype)
QL 9:ca2e6010d9e2 97 { static_cast<QSignal>(0), u8_0, u8_0 },
QL 9:ca2e6010d9e2 98 { static_cast<QSignal>(1), u8_0, u8_0 },
QL 9:ca2e6010d9e2 99 { static_cast<QSignal>(2), u8_0, u8_0 },
QL 9:ca2e6010d9e2 100 { static_cast<QSignal>(3), u8_0, u8_0 }
QL 9:ca2e6010d9e2 101 #endif
QL 9:ca2e6010d9e2 102 };
QL 9:ca2e6010d9e2 103 //............................................................................
QL 9:ca2e6010d9e2 104 char_t const Q_ROM * Q_ROM_VAR QEP::getVersion(void) {
QL 9:ca2e6010d9e2 105 uint8_t const u8_zero = static_cast<uint8_t>('0');
QL 9:ca2e6010d9e2 106 static char_t const Q_ROM Q_ROM_VAR version[] = {
QL 9:ca2e6010d9e2 107 static_cast<char_t>(((QP_VERSION >> 12) & 0xFU) + u8_zero),
QL 9:ca2e6010d9e2 108 static_cast<char_t>('.'),
QL 9:ca2e6010d9e2 109 static_cast<char_t>(((QP_VERSION >> 8) & 0xFU) + u8_zero),
QL 9:ca2e6010d9e2 110 static_cast<char_t>('.'),
QL 9:ca2e6010d9e2 111 static_cast<char_t>(((QP_VERSION >> 4) & 0xFU) + u8_zero),
QL 9:ca2e6010d9e2 112 static_cast<char_t>((QP_VERSION & 0xFU) + u8_zero),
QL 9:ca2e6010d9e2 113 static_cast<char_t>('\0')
QL 9:ca2e6010d9e2 114 };
QL 9:ca2e6010d9e2 115 return version;
QL 9:ca2e6010d9e2 116 }
QL 9:ca2e6010d9e2 117
QL 9:ca2e6010d9e2 118 QP_END_
QL 9:ca2e6010d9e2 119
QL 9:ca2e6010d9e2 120 // "qhsm_top.cpp" ============================================================
QL 9:ca2e6010d9e2 121 /// \brief QHsm::top() implementation.
QL 9:ca2e6010d9e2 122
QL 9:ca2e6010d9e2 123 QP_BEGIN_
QL 9:ca2e6010d9e2 124
QL 9:ca2e6010d9e2 125 //............................................................................
QL 9:ca2e6010d9e2 126 QState QHsm::top(void * const, QEvt const * const) {
QL 9:ca2e6010d9e2 127 return Q_RET_IGNORED; // the top state ignores all events
QL 9:ca2e6010d9e2 128 }
QL 9:ca2e6010d9e2 129
QL 9:ca2e6010d9e2 130 QP_END_
QL 9:ca2e6010d9e2 131
QL 9:ca2e6010d9e2 132 // "qhsm_ini.cpp" ============================================================
QL 9:ca2e6010d9e2 133 /// \brief QHsm::init() implementation.
QL 9:ca2e6010d9e2 134
QL 9:ca2e6010d9e2 135 QP_BEGIN_
QL 9:ca2e6010d9e2 136
QL 9:ca2e6010d9e2 137 //............................................................................
QL 9:ca2e6010d9e2 138 QHsm::~QHsm() {
QL 9:ca2e6010d9e2 139 }
QL 9:ca2e6010d9e2 140 //............................................................................
QL 9:ca2e6010d9e2 141 void QHsm::init(QEvt const * const e) {
QL 9:ca2e6010d9e2 142 QStateHandler t = m_state;
QL 9:ca2e6010d9e2 143
QL 9:ca2e6010d9e2 144 Q_REQUIRE((m_temp != Q_STATE_CAST(0)) // ctor must be executed
QL 9:ca2e6010d9e2 145 && (t == Q_STATE_CAST(&QHsm::top))); // initial tran. NOT taken
QL 9:ca2e6010d9e2 146
QL 9:ca2e6010d9e2 147 // the top-most initial transition must be taken
QL 9:ca2e6010d9e2 148 Q_ALLEGE((*m_temp)(this, e) == Q_RET_TRAN);
QL 9:ca2e6010d9e2 149
QL 9:ca2e6010d9e2 150 QS_CRIT_STAT_
QL 9:ca2e6010d9e2 151 do { // drill into the target...
QL 9:ca2e6010d9e2 152 QStateHandler path[QEP_MAX_NEST_DEPTH_];
QL 9:ca2e6010d9e2 153 int8_t ip = s8_0; // transition entry path index
QL 9:ca2e6010d9e2 154
QL 9:ca2e6010d9e2 155 QS_BEGIN_(QS_QEP_STATE_INIT, QS::smObj_, this)
QL 9:ca2e6010d9e2 156 QS_OBJ_(this); // this state machine object
QL 9:ca2e6010d9e2 157 QS_FUN_(t); // the source state
QL 9:ca2e6010d9e2 158 QS_FUN_(m_temp); // the target of the initial transition
QL 9:ca2e6010d9e2 159 QS_END_()
QL 9:ca2e6010d9e2 160
QL 9:ca2e6010d9e2 161 path[0] = m_temp;
QL 9:ca2e6010d9e2 162 (void)QEP_TRIG_(m_temp, QEP_EMPTY_SIG_);
QL 9:ca2e6010d9e2 163 while (m_temp != t) {
QL 9:ca2e6010d9e2 164 ++ip;
QL 9:ca2e6010d9e2 165 path[ip] = m_temp;
QL 9:ca2e6010d9e2 166 (void)QEP_TRIG_(m_temp, QEP_EMPTY_SIG_);
QL 9:ca2e6010d9e2 167 }
QL 9:ca2e6010d9e2 168 m_temp = path[0];
QL 9:ca2e6010d9e2 169 // entry path must not overflow
QL 9:ca2e6010d9e2 170 Q_ASSERT(ip < QEP_MAX_NEST_DEPTH_);
QL 9:ca2e6010d9e2 171
QL 9:ca2e6010d9e2 172 do { // retrace the entry path in reverse (desired) order...
QL 9:ca2e6010d9e2 173 QEP_ENTER_(path[ip]); // enter path[ip]
QL 9:ca2e6010d9e2 174 --ip;
QL 9:ca2e6010d9e2 175 } while (ip >= s8_0);
QL 9:ca2e6010d9e2 176
QL 9:ca2e6010d9e2 177 t = path[0]; // current state becomes the new source
QL 9:ca2e6010d9e2 178 } while (QEP_TRIG_(t, Q_INIT_SIG) == Q_RET_TRAN);
QL 9:ca2e6010d9e2 179
QL 9:ca2e6010d9e2 180 QS_BEGIN_(QS_QEP_INIT_TRAN, QS::smObj_, this)
QL 9:ca2e6010d9e2 181 QS_TIME_(); // time stamp
QL 9:ca2e6010d9e2 182 QS_OBJ_(this); // this state machine object
QL 9:ca2e6010d9e2 183 QS_FUN_(t); // the new active state
QL 9:ca2e6010d9e2 184 QS_END_()
QL 9:ca2e6010d9e2 185
QL 9:ca2e6010d9e2 186 m_state = t; // change the current active state
QL 9:ca2e6010d9e2 187 m_temp = t; // mark the configuration as stable
QL 9:ca2e6010d9e2 188 }
QL 9:ca2e6010d9e2 189
QL 9:ca2e6010d9e2 190 QP_END_
QL 9:ca2e6010d9e2 191
QL 9:ca2e6010d9e2 192 // "qhsm_dis.cpp" ============================================================
QL 9:ca2e6010d9e2 193 /// \brief QHsm::dispatch() implementation.
QL 9:ca2e6010d9e2 194
QL 9:ca2e6010d9e2 195 QP_BEGIN_
QL 9:ca2e6010d9e2 196
QL 9:ca2e6010d9e2 197 //............................................................................
QL 9:ca2e6010d9e2 198 void QHsm::dispatch(QEvt const * const e) {
QL 9:ca2e6010d9e2 199 QStateHandler t = m_state;
QL 9:ca2e6010d9e2 200
QL 9:ca2e6010d9e2 201 Q_REQUIRE(t == m_temp); // the state configuration must be stable
QL 9:ca2e6010d9e2 202
QL 9:ca2e6010d9e2 203 QStateHandler s;
QL 9:ca2e6010d9e2 204 QState r;
QL 9:ca2e6010d9e2 205 QS_CRIT_STAT_
QL 9:ca2e6010d9e2 206
QL 9:ca2e6010d9e2 207 QS_BEGIN_(QS_QEP_DISPATCH, QS::smObj_, this)
QL 9:ca2e6010d9e2 208 QS_TIME_(); // time stamp
QL 9:ca2e6010d9e2 209 QS_SIG_(e->sig); // the signal of the event
QL 9:ca2e6010d9e2 210 QS_OBJ_(this); // this state machine object
QL 9:ca2e6010d9e2 211 QS_FUN_(t); // the current state
QL 9:ca2e6010d9e2 212 QS_END_()
QL 9:ca2e6010d9e2 213
QL 9:ca2e6010d9e2 214 do { // process the event hierarchically...
QL 9:ca2e6010d9e2 215 s = m_temp;
QL 9:ca2e6010d9e2 216 r = (*s)(this, e); // invoke state handler s
QL 9:ca2e6010d9e2 217
QL 9:ca2e6010d9e2 218 if (r == Q_RET_UNHANDLED) { // unhandled due to a guard?
QL 9:ca2e6010d9e2 219
QL 9:ca2e6010d9e2 220 QS_BEGIN_(QS_QEP_UNHANDLED, QS::smObj_, this)
QL 9:ca2e6010d9e2 221 QS_SIG_(e->sig); // the signal of the event
QL 9:ca2e6010d9e2 222 QS_OBJ_(this); // this state machine object
QL 9:ca2e6010d9e2 223 QS_FUN_(s); // the current state
QL 9:ca2e6010d9e2 224 QS_END_()
QL 9:ca2e6010d9e2 225
QL 9:ca2e6010d9e2 226 r = QEP_TRIG_(s, QEP_EMPTY_SIG_); // find superstate of s
QL 9:ca2e6010d9e2 227 }
QL 9:ca2e6010d9e2 228 } while (r == Q_RET_SUPER);
QL 9:ca2e6010d9e2 229
QL 9:ca2e6010d9e2 230 if (r == Q_RET_TRAN) { // transition taken?
QL 9:ca2e6010d9e2 231 QStateHandler path[QEP_MAX_NEST_DEPTH_];
QL 9:ca2e6010d9e2 232 int8_t ip = s8_n1; // transition entry path index
QL 9:ca2e6010d9e2 233 int8_t iq; // helper transition entry path index
QL 9:ca2e6010d9e2 234 #ifdef Q_SPY
QL 9:ca2e6010d9e2 235 QStateHandler src = s; // save the transition source for tracing
QL 9:ca2e6010d9e2 236 #endif
QL 9:ca2e6010d9e2 237
QL 9:ca2e6010d9e2 238 path[0] = m_temp; // save the target of the transition
QL 9:ca2e6010d9e2 239 path[1] = t;
QL 9:ca2e6010d9e2 240
QL 9:ca2e6010d9e2 241 while (t != s) { // exit current state to transition source s...
QL 9:ca2e6010d9e2 242 if (QEP_TRIG_(t, Q_EXIT_SIG) == Q_RET_HANDLED) { //exit handled?
QL 9:ca2e6010d9e2 243 QS_BEGIN_(QS_QEP_STATE_EXIT, QS::smObj_, this)
QL 9:ca2e6010d9e2 244 QS_OBJ_(this); // this state machine object
QL 9:ca2e6010d9e2 245 QS_FUN_(t); // the exited state
QL 9:ca2e6010d9e2 246 QS_END_()
QL 9:ca2e6010d9e2 247
QL 9:ca2e6010d9e2 248 (void)QEP_TRIG_(t, QEP_EMPTY_SIG_); // find superstate of t
QL 9:ca2e6010d9e2 249 }
QL 9:ca2e6010d9e2 250 t = m_temp; // m_temp holds the superstate
QL 9:ca2e6010d9e2 251 }
QL 9:ca2e6010d9e2 252
QL 9:ca2e6010d9e2 253 t = path[0]; // target of the transition
QL 9:ca2e6010d9e2 254
QL 9:ca2e6010d9e2 255 if (s == t) { // (a) check source==target (transition to self)
QL 9:ca2e6010d9e2 256 QEP_EXIT_(s); // exit the source
QL 9:ca2e6010d9e2 257 ip = s8_0; // enter the target
QL 9:ca2e6010d9e2 258 }
QL 9:ca2e6010d9e2 259 else {
QL 9:ca2e6010d9e2 260 (void)QEP_TRIG_(t, QEP_EMPTY_SIG_); // superstate of target
QL 9:ca2e6010d9e2 261 t = m_temp;
QL 9:ca2e6010d9e2 262 if (s == t) { // (b) check source==target->super
QL 9:ca2e6010d9e2 263 ip = s8_0; // enter the target
QL 9:ca2e6010d9e2 264 }
QL 9:ca2e6010d9e2 265 else {
QL 9:ca2e6010d9e2 266 (void)QEP_TRIG_(s, QEP_EMPTY_SIG_); // superstate of src
QL 9:ca2e6010d9e2 267 // (c) check source->super==target->super
QL 9:ca2e6010d9e2 268 if (m_temp == t) {
QL 9:ca2e6010d9e2 269 QEP_EXIT_(s); // exit the source
QL 9:ca2e6010d9e2 270 ip = s8_0; // enter the target
QL 9:ca2e6010d9e2 271 }
QL 9:ca2e6010d9e2 272 else {
QL 9:ca2e6010d9e2 273 // (d) check source->super==target
QL 9:ca2e6010d9e2 274 if (m_temp == path[0]) {
QL 9:ca2e6010d9e2 275 QEP_EXIT_(s); // exit the source
QL 9:ca2e6010d9e2 276 }
QL 9:ca2e6010d9e2 277 else { // (e) check rest of source==target->super->super..
QL 9:ca2e6010d9e2 278 // and store the entry path along the way
QL 9:ca2e6010d9e2 279 //
QL 9:ca2e6010d9e2 280 iq = s8_0; // indicate LCA not found
QL 9:ca2e6010d9e2 281 ip = s8_1; // enter target's superst
QL 9:ca2e6010d9e2 282 path[1] = t; // save the superstate of target
QL 9:ca2e6010d9e2 283 t = m_temp; // save source->super
QL 9:ca2e6010d9e2 284 // find target->super->super
QL 9:ca2e6010d9e2 285 r = QEP_TRIG_(path[1], QEP_EMPTY_SIG_);
QL 9:ca2e6010d9e2 286 while (r == Q_RET_SUPER) {
QL 9:ca2e6010d9e2 287 ++ip;
QL 9:ca2e6010d9e2 288 path[ip] = m_temp; // store the entry path
QL 9:ca2e6010d9e2 289 if (m_temp == s) { // is it the source?
QL 9:ca2e6010d9e2 290 // indicate that LCA found
QL 9:ca2e6010d9e2 291 iq = s8_1;
QL 9:ca2e6010d9e2 292 // entry path must not overflow
QL 9:ca2e6010d9e2 293 Q_ASSERT(ip < QEP_MAX_NEST_DEPTH_);
QL 9:ca2e6010d9e2 294 --ip; // do not enter the source
QL 9:ca2e6010d9e2 295 r = Q_RET_HANDLED; // terminate the loop
QL 9:ca2e6010d9e2 296 }
QL 9:ca2e6010d9e2 297 else { // it is not the source, keep going up
QL 9:ca2e6010d9e2 298 r = QEP_TRIG_(m_temp, QEP_EMPTY_SIG_);
QL 9:ca2e6010d9e2 299 }
QL 9:ca2e6010d9e2 300 }
QL 9:ca2e6010d9e2 301 if (iq == s8_0) { // LCA found yet?
QL 9:ca2e6010d9e2 302
QL 9:ca2e6010d9e2 303 // entry path must not overflow
QL 9:ca2e6010d9e2 304 Q_ASSERT(ip < QEP_MAX_NEST_DEPTH_);
QL 9:ca2e6010d9e2 305
QL 9:ca2e6010d9e2 306 QEP_EXIT_(s); // exit the source
QL 9:ca2e6010d9e2 307
QL 9:ca2e6010d9e2 308 // (f) check the rest of source->super
QL 9:ca2e6010d9e2 309 // == target->super->super...
QL 9:ca2e6010d9e2 310 //
QL 9:ca2e6010d9e2 311 iq = ip;
QL 9:ca2e6010d9e2 312 r = Q_RET_IGNORED; // indicate LCA NOT found
QL 9:ca2e6010d9e2 313 do {
QL 9:ca2e6010d9e2 314 if (t == path[iq]) { // is this the LCA?
QL 9:ca2e6010d9e2 315 r = Q_RET_HANDLED; // indicate LCA found
QL 9:ca2e6010d9e2 316 // do not enter LCA
QL 9:ca2e6010d9e2 317 ip = static_cast<int8_t>(iq - s8_1);
QL 9:ca2e6010d9e2 318 // terminate the loop
QL 9:ca2e6010d9e2 319 iq = s8_n1;
QL 9:ca2e6010d9e2 320 }
QL 9:ca2e6010d9e2 321 else {
QL 9:ca2e6010d9e2 322 --iq; // try lower superstate of target
QL 9:ca2e6010d9e2 323 }
QL 9:ca2e6010d9e2 324 } while (iq >= s8_0);
QL 9:ca2e6010d9e2 325
QL 9:ca2e6010d9e2 326 if (r != Q_RET_HANDLED) { // LCA not found yet?
QL 9:ca2e6010d9e2 327 // (g) check each source->super->...
QL 9:ca2e6010d9e2 328 // for each target->super...
QL 9:ca2e6010d9e2 329 //
QL 9:ca2e6010d9e2 330 r = Q_RET_IGNORED; // keep looping
QL 9:ca2e6010d9e2 331 do {
QL 9:ca2e6010d9e2 332 // exit t unhandled?
QL 9:ca2e6010d9e2 333 if (QEP_TRIG_(t, Q_EXIT_SIG)
QL 9:ca2e6010d9e2 334 == Q_RET_HANDLED)
QL 9:ca2e6010d9e2 335 {
QL 9:ca2e6010d9e2 336 QS_BEGIN_(QS_QEP_STATE_EXIT,
QL 9:ca2e6010d9e2 337 QS::smObj_, this)
QL 9:ca2e6010d9e2 338 QS_OBJ_(this);
QL 9:ca2e6010d9e2 339 QS_FUN_(t);
QL 9:ca2e6010d9e2 340 QS_END_()
QL 9:ca2e6010d9e2 341
QL 9:ca2e6010d9e2 342 (void)QEP_TRIG_(t, QEP_EMPTY_SIG_);
QL 9:ca2e6010d9e2 343 }
QL 9:ca2e6010d9e2 344 t = m_temp; // set to super of t
QL 9:ca2e6010d9e2 345 iq = ip;
QL 9:ca2e6010d9e2 346 do {
QL 9:ca2e6010d9e2 347 if (t == path[iq]) { // is this LCA?
QL 9:ca2e6010d9e2 348 // do not enter LCA
QL 9:ca2e6010d9e2 349 ip = static_cast<int8_t>(iq-s8_1);
QL 9:ca2e6010d9e2 350 // break out of the inner loop
QL 9:ca2e6010d9e2 351 iq = s8_n1;
QL 9:ca2e6010d9e2 352 r = Q_RET_HANDLED; // break outer
QL 9:ca2e6010d9e2 353 }
QL 9:ca2e6010d9e2 354 else {
QL 9:ca2e6010d9e2 355 --iq;
QL 9:ca2e6010d9e2 356 }
QL 9:ca2e6010d9e2 357 } while (iq >= s8_0);
QL 9:ca2e6010d9e2 358 } while (r != Q_RET_HANDLED);
QL 9:ca2e6010d9e2 359 }
QL 9:ca2e6010d9e2 360 }
QL 9:ca2e6010d9e2 361 }
QL 9:ca2e6010d9e2 362 }
QL 9:ca2e6010d9e2 363 }
QL 9:ca2e6010d9e2 364 }
QL 9:ca2e6010d9e2 365 // retrace the entry path in reverse (desired) order...
QL 9:ca2e6010d9e2 366 for (; ip >= s8_0; --ip) {
QL 9:ca2e6010d9e2 367 QEP_ENTER_(path[ip]); // enter path[ip]
QL 9:ca2e6010d9e2 368 }
QL 9:ca2e6010d9e2 369 t = path[0]; // stick the target into register
QL 9:ca2e6010d9e2 370 m_temp = t; // update the next state
QL 9:ca2e6010d9e2 371
QL 9:ca2e6010d9e2 372 // drill into the target hierarchy...
QL 9:ca2e6010d9e2 373 while (QEP_TRIG_(t, Q_INIT_SIG) == Q_RET_TRAN) {
QL 9:ca2e6010d9e2 374
QL 9:ca2e6010d9e2 375 QS_BEGIN_(QS_QEP_STATE_INIT, QS::smObj_, this)
QL 9:ca2e6010d9e2 376 QS_OBJ_(this); // this state machine object
QL 9:ca2e6010d9e2 377 QS_FUN_(t); // the source (pseudo)state
QL 9:ca2e6010d9e2 378 QS_FUN_(m_temp); // the target of the transition
QL 9:ca2e6010d9e2 379 QS_END_()
QL 9:ca2e6010d9e2 380
QL 9:ca2e6010d9e2 381 ip = s8_0;
QL 9:ca2e6010d9e2 382 path[0] = m_temp;
QL 9:ca2e6010d9e2 383 (void)QEP_TRIG_(m_temp, QEP_EMPTY_SIG_); // find superstate
QL 9:ca2e6010d9e2 384 while (m_temp != t) {
QL 9:ca2e6010d9e2 385 ++ip;
QL 9:ca2e6010d9e2 386 path[ip] = m_temp;
QL 9:ca2e6010d9e2 387 (void)QEP_TRIG_(m_temp, QEP_EMPTY_SIG_); // find superstate
QL 9:ca2e6010d9e2 388 }
QL 9:ca2e6010d9e2 389 m_temp = path[0];
QL 9:ca2e6010d9e2 390 // entry path must not overflow
QL 9:ca2e6010d9e2 391 Q_ASSERT(ip < QEP_MAX_NEST_DEPTH_);
QL 9:ca2e6010d9e2 392
QL 9:ca2e6010d9e2 393 do { // retrace the entry path in reverse (correct) order...
QL 9:ca2e6010d9e2 394 QEP_ENTER_(path[ip]); // enter path[ip]
QL 9:ca2e6010d9e2 395 --ip;
QL 9:ca2e6010d9e2 396 } while (ip >= s8_0);
QL 9:ca2e6010d9e2 397
QL 9:ca2e6010d9e2 398 t = path[0];
QL 9:ca2e6010d9e2 399 }
QL 9:ca2e6010d9e2 400
QL 9:ca2e6010d9e2 401 QS_BEGIN_(QS_QEP_TRAN, QS::smObj_, this)
QL 9:ca2e6010d9e2 402 QS_TIME_(); // time stamp
QL 9:ca2e6010d9e2 403 QS_SIG_(e->sig); // the signal of the event
QL 9:ca2e6010d9e2 404 QS_OBJ_(this); // this state machine object
QL 9:ca2e6010d9e2 405 QS_FUN_(src); // the source of the transition
QL 9:ca2e6010d9e2 406 QS_FUN_(t); // the new active state
QL 9:ca2e6010d9e2 407 QS_END_()
QL 9:ca2e6010d9e2 408
QL 9:ca2e6010d9e2 409 }
QL 9:ca2e6010d9e2 410 else { // transition not taken
QL 9:ca2e6010d9e2 411 #ifdef Q_SPY
QL 9:ca2e6010d9e2 412 if (r == Q_RET_HANDLED) {
QL 9:ca2e6010d9e2 413
QL 9:ca2e6010d9e2 414 QS_BEGIN_(QS_QEP_INTERN_TRAN, QS::smObj_, this)
QL 9:ca2e6010d9e2 415 QS_TIME_(); // time stamp
QL 9:ca2e6010d9e2 416 QS_SIG_(e->sig); // the signal of the event
QL 9:ca2e6010d9e2 417 QS_OBJ_(this); // this state machine object
QL 9:ca2e6010d9e2 418 QS_FUN_(m_state); // the state that handled the event
QL 9:ca2e6010d9e2 419 QS_END_()
QL 9:ca2e6010d9e2 420
QL 9:ca2e6010d9e2 421 }
QL 9:ca2e6010d9e2 422 else {
QL 9:ca2e6010d9e2 423
QL 9:ca2e6010d9e2 424 QS_BEGIN_(QS_QEP_IGNORED, QS::smObj_, this)
QL 9:ca2e6010d9e2 425 QS_TIME_(); // time stamp
QL 9:ca2e6010d9e2 426 QS_SIG_(e->sig); // the signal of the event
QL 9:ca2e6010d9e2 427 QS_OBJ_(this); // this state machine object
QL 9:ca2e6010d9e2 428 QS_FUN_(m_state); // the current state
QL 9:ca2e6010d9e2 429 QS_END_()
QL 9:ca2e6010d9e2 430
QL 9:ca2e6010d9e2 431 }
QL 9:ca2e6010d9e2 432 #endif
QL 9:ca2e6010d9e2 433 }
QL 9:ca2e6010d9e2 434
QL 9:ca2e6010d9e2 435 m_state = t; // change the current active state
QL 9:ca2e6010d9e2 436 m_temp = t; // mark the configuration as stable
QL 9:ca2e6010d9e2 437 }
QL 9:ca2e6010d9e2 438
QL 9:ca2e6010d9e2 439 QP_END_
QL 9:ca2e6010d9e2 440
QL 9:ca2e6010d9e2 441 // "qf_pkg.h" ================================================================
QL 9:ca2e6010d9e2 442 /// \brief Internal (package scope) QF/C++ interface.
QL 9:ca2e6010d9e2 443
QL 9:ca2e6010d9e2 444 /// \brief helper macro to cast const away from an event pointer \a e_
QL 9:ca2e6010d9e2 445 #define QF_EVT_CONST_CAST_(e_) const_cast<QEvt *>(e_)
QL 9:ca2e6010d9e2 446
QL 9:ca2e6010d9e2 447 QP_BEGIN_
QL 9:ca2e6010d9e2 448 // QF-specific critical section
QL 9:ca2e6010d9e2 449 #ifndef QF_CRIT_STAT_TYPE
QL 9:ca2e6010d9e2 450 /// \brief This is an internal macro for defining the critical section
QL 9:ca2e6010d9e2 451 /// status type.
QL 9:ca2e6010d9e2 452 ///
QL 9:ca2e6010d9e2 453 /// The purpose of this macro is to enable writing the same code for the
QL 9:ca2e6010d9e2 454 /// case when critical sectgion status type is defined and when it is not.
QL 9:ca2e6010d9e2 455 /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
QL 9:ca2e6010d9e2 456 /// provides the definition of the critical section status varaible.
QL 9:ca2e6010d9e2 457 /// Otherwise this macro is empty.
QL 9:ca2e6010d9e2 458 /// \sa #QF_CRIT_STAT_TYPE
QL 9:ca2e6010d9e2 459 ///
QL 9:ca2e6010d9e2 460 #define QF_CRIT_STAT_
QL 9:ca2e6010d9e2 461
QL 9:ca2e6010d9e2 462 /// \brief This is an internal macro for entering a critical section.
QL 9:ca2e6010d9e2 463 ///
QL 9:ca2e6010d9e2 464 /// The purpose of this macro is to enable writing the same code for the
QL 9:ca2e6010d9e2 465 /// case when critical sectgion status type is defined and when it is not.
QL 9:ca2e6010d9e2 466 /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
QL 9:ca2e6010d9e2 467 /// invokes #QF_CRIT_ENTRY passing the key variable as the parameter.
QL 9:ca2e6010d9e2 468 /// Otherwise #QF_CRIT_ENTRY is invoked with a dummy parameter.
QL 9:ca2e6010d9e2 469 /// \sa #QF_CRIT_ENTRY
QL 9:ca2e6010d9e2 470 ///
QL 9:ca2e6010d9e2 471 #define QF_CRIT_ENTRY_() QF_CRIT_ENTRY(dummy)
QL 9:ca2e6010d9e2 472
QL 9:ca2e6010d9e2 473 /// \brief This is an internal macro for exiting a cricial section.
QL 9:ca2e6010d9e2 474 ///
QL 9:ca2e6010d9e2 475 /// The purpose of this macro is to enable writing the same code for the
QL 9:ca2e6010d9e2 476 /// case when critical sectgion status type is defined and when it is not.
QL 9:ca2e6010d9e2 477 /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
QL 9:ca2e6010d9e2 478 /// invokes #QF_CRIT_EXIT passing the key variable as the parameter.
QL 9:ca2e6010d9e2 479 /// Otherwise #QF_CRIT_EXIT is invoked with a dummy parameter.
QL 9:ca2e6010d9e2 480 /// \sa #QF_CRIT_EXIT
QL 9:ca2e6010d9e2 481 ///
QL 9:ca2e6010d9e2 482 #define QF_CRIT_EXIT_() QF_CRIT_EXIT(dummy)
QL 9:ca2e6010d9e2 483
QL 9:ca2e6010d9e2 484 #else
QL 9:ca2e6010d9e2 485 #define QF_CRIT_STAT_ QF_CRIT_STAT_TYPE critStat_;
QL 9:ca2e6010d9e2 486 #define QF_CRIT_ENTRY_() QF_CRIT_ENTRY(critStat_)
QL 9:ca2e6010d9e2 487 #define QF_CRIT_EXIT_() QF_CRIT_EXIT(critStat_)
QL 9:ca2e6010d9e2 488 #endif
QL 9:ca2e6010d9e2 489
QL 9:ca2e6010d9e2 490 // package-scope objects -----------------------------------------------------
QL 9:ca2e6010d9e2 491 extern QTimeEvt *QF_timeEvtListHead_; ///< head of linked list of time events
QL 9:ca2e6010d9e2 492 extern QF_EPOOL_TYPE_ QF_pool_[QF_MAX_EPOOL]; ///< allocate event pools
QL 9:ca2e6010d9e2 493 extern uint8_t QF_maxPool_; ///< # of initialized event pools
QL 9:ca2e6010d9e2 494 extern QSubscrList *QF_subscrList_; ///< the subscriber list array
QL 9:ca2e6010d9e2 495 extern enum_t QF_maxSignal_; ///< the maximum published signal
QL 9:ca2e6010d9e2 496
QL 9:ca2e6010d9e2 497 //............................................................................
QL 9:ca2e6010d9e2 498 /// \brief Structure representing a free block in the Native QF Memory Pool
QL 9:ca2e6010d9e2 499 /// \sa ::QMPool
QL 9:ca2e6010d9e2 500 struct QFreeBlock {
QL 9:ca2e6010d9e2 501 QFreeBlock *m_next;
QL 9:ca2e6010d9e2 502 };
QL 9:ca2e6010d9e2 503
QL 9:ca2e6010d9e2 504 //////////////////////////////////////////////////////////////////////////////
QL 9:ca2e6010d9e2 505 // internal helper inline functions
QL 9:ca2e6010d9e2 506
QL 9:ca2e6010d9e2 507 /// \brief access to the poolId_ of an event \a e
QL 9:ca2e6010d9e2 508 inline uint8_t QF_EVT_POOL_ID_(QEvt const * const e) { return e->poolId_; }
QL 9:ca2e6010d9e2 509
QL 9:ca2e6010d9e2 510 /// \brief access to the refCtr_ of an event \a e
QL 9:ca2e6010d9e2 511 inline uint8_t QF_EVT_REF_CTR_(QEvt const * const e) { return e->refCtr_; }
QL 9:ca2e6010d9e2 512
QL 9:ca2e6010d9e2 513 /// \brief increment the refCtr_ of an event \a e
QL 9:ca2e6010d9e2 514 inline void QF_EVT_REF_CTR_INC_(QEvt const * const e) {
QL 9:ca2e6010d9e2 515 ++(QF_EVT_CONST_CAST_(e))->refCtr_;
QL 9:ca2e6010d9e2 516 }
QL 9:ca2e6010d9e2 517
QL 9:ca2e6010d9e2 518 /// \brief decrement the refCtr_ of an event \a e
QL 9:ca2e6010d9e2 519 inline void QF_EVT_REF_CTR_DEC_(QEvt const * const e) {
QL 9:ca2e6010d9e2 520 --(QF_EVT_CONST_CAST_(e))->refCtr_;
QL 9:ca2e6010d9e2 521 }
QL 9:ca2e6010d9e2 522
QL 9:ca2e6010d9e2 523 //////////////////////////////////////////////////////////////////////////////
QL 9:ca2e6010d9e2 524 // internal frequently used srongly-typed constants
QL 9:ca2e6010d9e2 525
QL 9:ca2e6010d9e2 526 QTimeEvtCtr const tc_0 = static_cast<QTimeEvtCtr>(0);
QL 9:ca2e6010d9e2 527
QL 9:ca2e6010d9e2 528 void * const null_void = static_cast<void *>(0);
QL 9:ca2e6010d9e2 529 QEvt const * const null_evt = static_cast<QEvt const *>(0);
QL 9:ca2e6010d9e2 530 QTimeEvt * const null_tevt = static_cast<QTimeEvt *>(0);
QL 9:ca2e6010d9e2 531 QActive * const null_act = static_cast<QActive *>(0);
QL 9:ca2e6010d9e2 532
QL 9:ca2e6010d9e2 533 QP_END_
QL 9:ca2e6010d9e2 534
QL 9:ca2e6010d9e2 535 /// \brief access element at index \a i_ from the base pointer \a base_
QL 9:ca2e6010d9e2 536 #define QF_PTR_AT_(base_, i_) (base_[i_])
QL 9:ca2e6010d9e2 537
QL 9:ca2e6010d9e2 538 //////////////////////////////////////////////////////////////////////////////
QL 9:ca2e6010d9e2 539 #ifdef Q_SPY // QS software tracing enabled?
QL 9:ca2e6010d9e2 540
QL 9:ca2e6010d9e2 541 #if (QF_EQUEUE_CTR_SIZE == 1)
QL 9:ca2e6010d9e2 542
QL 9:ca2e6010d9e2 543 /// \brief Internal QS macro to output an unformatted event queue
QL 9:ca2e6010d9e2 544 /// counter data element
QL 9:ca2e6010d9e2 545 /// \note the counter size depends on the macro #QF_EQUEUE_CTR_SIZE.
QL 9:ca2e6010d9e2 546 #define QS_EQC_(ctr_) QS::u8_(ctr_)
QL 9:ca2e6010d9e2 547 #elif (QF_EQUEUE_CTR_SIZE == 2)
QL 9:ca2e6010d9e2 548 #define QS_EQC_(ctr_) QS::u16_(ctr_)
QL 9:ca2e6010d9e2 549 #elif (QF_EQUEUE_CTR_SIZE == 4)
QL 9:ca2e6010d9e2 550 #define QS_EQC_(ctr_) QS::u32_(ctr_)
QL 9:ca2e6010d9e2 551 #else
QL 9:ca2e6010d9e2 552 #error "QF_EQUEUE_CTR_SIZE not defined"
QL 9:ca2e6010d9e2 553 #endif
QL 9:ca2e6010d9e2 554
QL 9:ca2e6010d9e2 555
QL 9:ca2e6010d9e2 556 #if (QF_EVENT_SIZ_SIZE == 1)
QL 9:ca2e6010d9e2 557
QL 9:ca2e6010d9e2 558 /// \brief Internal QS macro to output an unformatted event size
QL 9:ca2e6010d9e2 559 /// data element
QL 9:ca2e6010d9e2 560 /// \note the event size depends on the macro #QF_EVENT_SIZ_SIZE.
QL 9:ca2e6010d9e2 561 #define QS_EVS_(size_) QS::u8_(size_)
QL 9:ca2e6010d9e2 562 #elif (QF_EVENT_SIZ_SIZE == 2)
QL 9:ca2e6010d9e2 563 #define QS_EVS_(size_) QS::u16_(size_)
QL 9:ca2e6010d9e2 564 #elif (QF_EVENT_SIZ_SIZE == 4)
QL 9:ca2e6010d9e2 565 #define QS_EVS_(size_) QS::u32_(size_)
QL 9:ca2e6010d9e2 566 #endif
QL 9:ca2e6010d9e2 567
QL 9:ca2e6010d9e2 568
QL 9:ca2e6010d9e2 569 #if (QF_MPOOL_SIZ_SIZE == 1)
QL 9:ca2e6010d9e2 570
QL 9:ca2e6010d9e2 571 /// \brief Internal QS macro to output an unformatted memory pool
QL 9:ca2e6010d9e2 572 /// block-size data element
QL 9:ca2e6010d9e2 573 /// \note the block-size depends on the macro #QF_MPOOL_SIZ_SIZE.
QL 9:ca2e6010d9e2 574 #define QS_MPS_(size_) QS::u8_(size_)
QL 9:ca2e6010d9e2 575 #elif (QF_MPOOL_SIZ_SIZE == 2)
QL 9:ca2e6010d9e2 576 #define QS_MPS_(size_) QS::u16_(size_)
QL 9:ca2e6010d9e2 577 #elif (QF_MPOOL_SIZ_SIZE == 4)
QL 9:ca2e6010d9e2 578 #define QS_MPS_(size_) QS::u32_(size_)
QL 9:ca2e6010d9e2 579 #endif
QL 9:ca2e6010d9e2 580
QL 9:ca2e6010d9e2 581 #if (QF_MPOOL_CTR_SIZE == 1)
QL 9:ca2e6010d9e2 582
QL 9:ca2e6010d9e2 583 /// \brief Internal QS macro to output an unformatted memory pool
QL 9:ca2e6010d9e2 584 /// block-counter data element
QL 9:ca2e6010d9e2 585 /// \note the counter size depends on the macro #QF_MPOOL_CTR_SIZE.
QL 9:ca2e6010d9e2 586 #define QS_MPC_(ctr_) QS::u8_(ctr_)
QL 9:ca2e6010d9e2 587 #elif (QF_MPOOL_CTR_SIZE == 2)
QL 9:ca2e6010d9e2 588 #define QS_MPC_(ctr_) QS::u16_(ctr_)
QL 9:ca2e6010d9e2 589 #elif (QF_MPOOL_CTR_SIZE == 4)
QL 9:ca2e6010d9e2 590 #define QS_MPC_(ctr_) QS::u32_(ctr_)
QL 9:ca2e6010d9e2 591 #endif
QL 9:ca2e6010d9e2 592
QL 9:ca2e6010d9e2 593
QL 9:ca2e6010d9e2 594 #if (QF_TIMEEVT_CTR_SIZE == 1)
QL 9:ca2e6010d9e2 595
QL 9:ca2e6010d9e2 596 /// \brief Internal QS macro to output an unformatted time event
QL 9:ca2e6010d9e2 597 /// tick-counter data element
QL 9:ca2e6010d9e2 598 /// \note the counter size depends on the macro #QF_TIMEEVT_CTR_SIZE.
QL 9:ca2e6010d9e2 599 #define QS_TEC_(ctr_) QS::u8_(ctr_)
QL 9:ca2e6010d9e2 600 #elif (QF_TIMEEVT_CTR_SIZE == 2)
QL 9:ca2e6010d9e2 601 #define QS_TEC_(ctr_) QS::u16_(ctr_)
QL 9:ca2e6010d9e2 602 #elif (QF_TIMEEVT_CTR_SIZE == 4)
QL 9:ca2e6010d9e2 603 #define QS_TEC_(ctr_) QS::u32_(ctr_)
QL 9:ca2e6010d9e2 604 #endif
QL 9:ca2e6010d9e2 605
QL 9:ca2e6010d9e2 606 #endif // Q_SPY
QL 9:ca2e6010d9e2 607
QL 9:ca2e6010d9e2 608 // "qa_defer.cpp" ============================================================
QL 9:ca2e6010d9e2 609 /// \brief QActive::defer() and QActive::recall() implementation.
QL 9:ca2e6010d9e2 610 ///
QL 9:ca2e6010d9e2 611
QL 9:ca2e6010d9e2 612 QP_BEGIN_
QL 9:ca2e6010d9e2 613
QL 9:ca2e6010d9e2 614 //............................................................................
QL 9:ca2e6010d9e2 615 void QActive::defer(QEQueue * const eq, QEvt const * const e) const {
QL 9:ca2e6010d9e2 616 eq->postFIFO(e);
QL 9:ca2e6010d9e2 617 }
QL 9:ca2e6010d9e2 618 //............................................................................
QL 9:ca2e6010d9e2 619 bool QActive::recall(QEQueue * const eq) {
QL 9:ca2e6010d9e2 620 QEvt const * const e = eq->get(); // try to get evt from deferred queue
QL 9:ca2e6010d9e2 621 bool const recalled = (e != null_evt); // event available?
QL 9:ca2e6010d9e2 622 if (recalled) {
QL 9:ca2e6010d9e2 623 postLIFO(e); // post it to the front of the Active Object's queue
QL 9:ca2e6010d9e2 624
QL 9:ca2e6010d9e2 625 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 626 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 627
QL 9:ca2e6010d9e2 628 if (QF_EVT_POOL_ID_(e) != u8_0) { // is it a dynamic event?
QL 9:ca2e6010d9e2 629
QL 9:ca2e6010d9e2 630 // after posting to the AO's queue the event must be referenced
QL 9:ca2e6010d9e2 631 // at least twice: once in the deferred event queue (eq->get()
QL 9:ca2e6010d9e2 632 // did NOT decrement the reference counter) and once in the
QL 9:ca2e6010d9e2 633 // AO's event queue.
QL 9:ca2e6010d9e2 634 Q_ASSERT(QF_EVT_REF_CTR_(e) > u8_1);
QL 9:ca2e6010d9e2 635
QL 9:ca2e6010d9e2 636 // we need to decrement the reference counter once, to account
QL 9:ca2e6010d9e2 637 // for removing the event from the deferred event queue.
QL 9:ca2e6010d9e2 638 //
QL 9:ca2e6010d9e2 639 QF_EVT_REF_CTR_DEC_(e); // decrement the reference counter
QL 9:ca2e6010d9e2 640 }
QL 9:ca2e6010d9e2 641
QL 9:ca2e6010d9e2 642 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 643 }
QL 9:ca2e6010d9e2 644 return recalled; // event not recalled
QL 9:ca2e6010d9e2 645 }
QL 9:ca2e6010d9e2 646
QL 9:ca2e6010d9e2 647 QP_END_
QL 9:ca2e6010d9e2 648
QL 9:ca2e6010d9e2 649
QL 9:ca2e6010d9e2 650 // "qa_fifo.cpp" =============================================================
QL 9:ca2e6010d9e2 651 /// \brief QActive::postFIFO() implementation.
QL 9:ca2e6010d9e2 652 ///
QL 9:ca2e6010d9e2 653 /// \note this source file is only included in the QF library when the native
QL 9:ca2e6010d9e2 654 /// QF active object queue is used (instead of a message queue of an RTOS).
QL 9:ca2e6010d9e2 655
QL 9:ca2e6010d9e2 656 QP_BEGIN_
QL 9:ca2e6010d9e2 657
QL 9:ca2e6010d9e2 658 //............................................................................
QL 9:ca2e6010d9e2 659 #ifndef Q_SPY
QL 9:ca2e6010d9e2 660 void QActive::postFIFO(QEvt const * const e) {
QL 9:ca2e6010d9e2 661 #else
QL 9:ca2e6010d9e2 662 void QActive::postFIFO(QEvt const * const e, void const * const sender) {
QL 9:ca2e6010d9e2 663 #endif
QL 9:ca2e6010d9e2 664
QL 9:ca2e6010d9e2 665 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 666 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 667
QL 9:ca2e6010d9e2 668 QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_FIFO, QS::aoObj_, this)
QL 9:ca2e6010d9e2 669 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 670 QS_OBJ_(sender); // the sender object
QL 9:ca2e6010d9e2 671 QS_SIG_(e->sig); // the signal of the event
QL 9:ca2e6010d9e2 672 QS_OBJ_(this); // this active object
QL 9:ca2e6010d9e2 673 QS_U8_(QF_EVT_POOL_ID_(e)); // the pool Id of the event
QL 9:ca2e6010d9e2 674 QS_U8_(QF_EVT_REF_CTR_(e)); // the ref count of the event
QL 9:ca2e6010d9e2 675 QS_EQC_(m_eQueue.m_nFree); // number of free entries
QL 9:ca2e6010d9e2 676 QS_EQC_(m_eQueue.m_nMin); // min number of free entries
QL 9:ca2e6010d9e2 677 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 678
QL 9:ca2e6010d9e2 679 if (QF_EVT_POOL_ID_(e) != u8_0) { // is it a dynamic event?
QL 9:ca2e6010d9e2 680 QF_EVT_REF_CTR_INC_(e); // increment the reference counter
QL 9:ca2e6010d9e2 681 }
QL 9:ca2e6010d9e2 682
QL 9:ca2e6010d9e2 683 if (m_eQueue.m_frontEvt == null_evt) { // is the queue empty?
QL 9:ca2e6010d9e2 684 m_eQueue.m_frontEvt = e; // deliver event directly
QL 9:ca2e6010d9e2 685 QACTIVE_EQUEUE_SIGNAL_(this); // signal the event queue
QL 9:ca2e6010d9e2 686 }
QL 9:ca2e6010d9e2 687 else { // queue is not empty, leave event in the ring-buffer
QL 9:ca2e6010d9e2 688 // queue must accept all posted events
QL 9:ca2e6010d9e2 689 Q_ASSERT(m_eQueue.m_nFree != static_cast<QEQueueCtr>(0));
QL 9:ca2e6010d9e2 690 // insert event pointer e into the buffer (FIFO)
QL 9:ca2e6010d9e2 691 QF_PTR_AT_(m_eQueue.m_ring, m_eQueue.m_head) = e;
QL 9:ca2e6010d9e2 692 if (m_eQueue.m_head == static_cast<QEQueueCtr>(0)) { // need to wrap?
QL 9:ca2e6010d9e2 693 m_eQueue.m_head = m_eQueue.m_end; // wrap around
QL 9:ca2e6010d9e2 694 }
QL 9:ca2e6010d9e2 695 --m_eQueue.m_head;
QL 9:ca2e6010d9e2 696
QL 9:ca2e6010d9e2 697 --m_eQueue.m_nFree; // update number of free events
QL 9:ca2e6010d9e2 698 if (m_eQueue.m_nMin > m_eQueue.m_nFree) {
QL 9:ca2e6010d9e2 699 m_eQueue.m_nMin = m_eQueue.m_nFree; // update minimum so far
QL 9:ca2e6010d9e2 700 }
QL 9:ca2e6010d9e2 701 }
QL 9:ca2e6010d9e2 702 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 703 }
QL 9:ca2e6010d9e2 704
QL 9:ca2e6010d9e2 705 QP_END_
QL 9:ca2e6010d9e2 706
QL 9:ca2e6010d9e2 707 // "qa_get_.cpp" =============================================================
QL 9:ca2e6010d9e2 708 /// \brief QActive::get_() and QF::getQueueMargin() definitions.
QL 9:ca2e6010d9e2 709 ///
QL 9:ca2e6010d9e2 710 /// \note this source file is only included in the QF library when the native
QL 9:ca2e6010d9e2 711 /// QF active object queue is used (instead of a message queue of an RTOS).
QL 9:ca2e6010d9e2 712
QL 9:ca2e6010d9e2 713 QP_BEGIN_
QL 9:ca2e6010d9e2 714
QL 9:ca2e6010d9e2 715 //............................................................................
QL 9:ca2e6010d9e2 716 QEvt const *QActive::get_(void) {
QL 9:ca2e6010d9e2 717 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 718 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 719
QL 9:ca2e6010d9e2 720 QACTIVE_EQUEUE_WAIT_(this); // wait for event to arrive directly
QL 9:ca2e6010d9e2 721
QL 9:ca2e6010d9e2 722 QEvt const *e = m_eQueue.m_frontEvt;
QL 9:ca2e6010d9e2 723
QL 9:ca2e6010d9e2 724 if (m_eQueue.m_nFree != m_eQueue.m_end) { //any events in the ring buffer?
QL 9:ca2e6010d9e2 725 // remove event from the tail
QL 9:ca2e6010d9e2 726 m_eQueue.m_frontEvt = QF_PTR_AT_(m_eQueue.m_ring, m_eQueue.m_tail);
QL 9:ca2e6010d9e2 727 if (m_eQueue.m_tail == static_cast<QEQueueCtr>(0)) { // need to wrap?
QL 9:ca2e6010d9e2 728 m_eQueue.m_tail = m_eQueue.m_end; // wrap around
QL 9:ca2e6010d9e2 729 }
QL 9:ca2e6010d9e2 730 --m_eQueue.m_tail;
QL 9:ca2e6010d9e2 731
QL 9:ca2e6010d9e2 732 ++m_eQueue.m_nFree; // one more free event in the ring buffer
QL 9:ca2e6010d9e2 733
QL 9:ca2e6010d9e2 734 QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_GET, QS::aoObj_, this)
QL 9:ca2e6010d9e2 735 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 736 QS_SIG_(e->sig); // the signal of this event
QL 9:ca2e6010d9e2 737 QS_OBJ_(this); // this active object
QL 9:ca2e6010d9e2 738 QS_U8_(QF_EVT_POOL_ID_(e)); // the pool Id of the event
QL 9:ca2e6010d9e2 739 QS_U8_(QF_EVT_REF_CTR_(e)); // the ref count of the event
QL 9:ca2e6010d9e2 740 QS_EQC_(m_eQueue.m_nFree); // number of free entries
QL 9:ca2e6010d9e2 741 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 742 }
QL 9:ca2e6010d9e2 743 else {
QL 9:ca2e6010d9e2 744 m_eQueue.m_frontEvt = null_evt; // the queue becomes empty
QL 9:ca2e6010d9e2 745 QACTIVE_EQUEUE_ONEMPTY_(this);
QL 9:ca2e6010d9e2 746
QL 9:ca2e6010d9e2 747 QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_GET_LAST, QS::aoObj_, this)
QL 9:ca2e6010d9e2 748 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 749 QS_SIG_(e->sig); // the signal of this event
QL 9:ca2e6010d9e2 750 QS_OBJ_(this); // this active object
QL 9:ca2e6010d9e2 751 QS_U8_(QF_EVT_POOL_ID_(e)); // the pool Id of the event
QL 9:ca2e6010d9e2 752 QS_U8_(QF_EVT_REF_CTR_(e)); // the ref count of the event
QL 9:ca2e6010d9e2 753 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 754 }
QL 9:ca2e6010d9e2 755 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 756 return e;
QL 9:ca2e6010d9e2 757 }
QL 9:ca2e6010d9e2 758 //............................................................................
QL 9:ca2e6010d9e2 759 uint32_t QF::getQueueMargin(uint8_t const prio) {
QL 9:ca2e6010d9e2 760 Q_REQUIRE((prio <= static_cast<uint8_t>(QF_MAX_ACTIVE))
QL 9:ca2e6010d9e2 761 && (active_[prio] != static_cast<QActive *>(0)));
QL 9:ca2e6010d9e2 762
QL 9:ca2e6010d9e2 763 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 764 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 765 uint32_t margin = static_cast<uint32_t>(active_[prio]->m_eQueue.m_nMin);
QL 9:ca2e6010d9e2 766 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 767
QL 9:ca2e6010d9e2 768 return margin;
QL 9:ca2e6010d9e2 769 }
QL 9:ca2e6010d9e2 770
QL 9:ca2e6010d9e2 771 QP_END_
QL 9:ca2e6010d9e2 772
QL 9:ca2e6010d9e2 773 // "qa_lifo.cpp" =============================================================
QL 9:ca2e6010d9e2 774 /// \brief QActive::postLIFO() implementation.
QL 9:ca2e6010d9e2 775 ///
QL 9:ca2e6010d9e2 776 /// \note this source file is only included in the QF library when the native
QL 9:ca2e6010d9e2 777 /// QF active object queue is used (instead of a message queue of an RTOS).
QL 9:ca2e6010d9e2 778
QL 9:ca2e6010d9e2 779 QP_BEGIN_
QL 9:ca2e6010d9e2 780
QL 9:ca2e6010d9e2 781 //............................................................................
QL 9:ca2e6010d9e2 782 void QActive::postLIFO(QEvt const * const e) {
QL 9:ca2e6010d9e2 783 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 784 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 785
QL 9:ca2e6010d9e2 786 QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_LIFO, QS::aoObj_, this)
QL 9:ca2e6010d9e2 787 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 788 QS_SIG_(e->sig); // the signal of this event
QL 9:ca2e6010d9e2 789 QS_OBJ_(this); // this active object
QL 9:ca2e6010d9e2 790 QS_U8_(QF_EVT_POOL_ID_(e)); // the pool Id of the event
QL 9:ca2e6010d9e2 791 QS_U8_(QF_EVT_REF_CTR_(e)); // the ref count of the event
QL 9:ca2e6010d9e2 792 QS_EQC_(m_eQueue.m_nFree); // number of free entries
QL 9:ca2e6010d9e2 793 QS_EQC_(m_eQueue.m_nMin); // min number of free entries
QL 9:ca2e6010d9e2 794 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 795
QL 9:ca2e6010d9e2 796 if (QF_EVT_POOL_ID_(e) != u8_0) { // is it a dynamic event?
QL 9:ca2e6010d9e2 797 QF_EVT_REF_CTR_INC_(e); // increment the reference counter
QL 9:ca2e6010d9e2 798 }
QL 9:ca2e6010d9e2 799
QL 9:ca2e6010d9e2 800 if (m_eQueue.m_frontEvt == null_evt) { // is the queue empty?
QL 9:ca2e6010d9e2 801 m_eQueue.m_frontEvt = e; // deliver event directly
QL 9:ca2e6010d9e2 802 QACTIVE_EQUEUE_SIGNAL_(this); // signal the event queue
QL 9:ca2e6010d9e2 803 }
QL 9:ca2e6010d9e2 804 else { // queue is not empty, leave event in the ring-buffer
QL 9:ca2e6010d9e2 805 // queue must accept all posted events
QL 9:ca2e6010d9e2 806 Q_ASSERT(m_eQueue.m_nFree != static_cast<QEQueueCtr>(0));
QL 9:ca2e6010d9e2 807
QL 9:ca2e6010d9e2 808 ++m_eQueue.m_tail;
QL 9:ca2e6010d9e2 809 if (m_eQueue.m_tail == m_eQueue.m_end) { // need to wrap the tail?
QL 9:ca2e6010d9e2 810 m_eQueue.m_tail = static_cast<QEQueueCtr>(0); // wrap around
QL 9:ca2e6010d9e2 811 }
QL 9:ca2e6010d9e2 812
QL 9:ca2e6010d9e2 813 QF_PTR_AT_(m_eQueue.m_ring, m_eQueue.m_tail) = m_eQueue.m_frontEvt;
QL 9:ca2e6010d9e2 814 m_eQueue.m_frontEvt = e; // put event to front
QL 9:ca2e6010d9e2 815
QL 9:ca2e6010d9e2 816 --m_eQueue.m_nFree; // update number of free events
QL 9:ca2e6010d9e2 817 if (m_eQueue.m_nMin > m_eQueue.m_nFree) {
QL 9:ca2e6010d9e2 818 m_eQueue.m_nMin = m_eQueue.m_nFree; // update minimum so far
QL 9:ca2e6010d9e2 819 }
QL 9:ca2e6010d9e2 820 }
QL 9:ca2e6010d9e2 821 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 822 }
QL 9:ca2e6010d9e2 823
QL 9:ca2e6010d9e2 824 QP_END_
QL 9:ca2e6010d9e2 825
QL 9:ca2e6010d9e2 826 // "qa_sub.cpp" ==============================================================
QL 9:ca2e6010d9e2 827 /// \brief QActive::subscribe() implementation.
QL 9:ca2e6010d9e2 828
QL 9:ca2e6010d9e2 829 QP_BEGIN_
QL 9:ca2e6010d9e2 830
QL 9:ca2e6010d9e2 831 //............................................................................
QL 9:ca2e6010d9e2 832 void QActive::subscribe(enum_t const sig) const {
QL 9:ca2e6010d9e2 833 uint8_t p = m_prio;
QL 9:ca2e6010d9e2 834 Q_REQUIRE((Q_USER_SIG <= sig)
QL 9:ca2e6010d9e2 835 && (sig < QF_maxSignal_)
QL 9:ca2e6010d9e2 836 && (u8_0 < p) && (p <= static_cast<uint8_t>(QF_MAX_ACTIVE))
QL 9:ca2e6010d9e2 837 && (QF::active_[p] == this));
QL 9:ca2e6010d9e2 838
QL 9:ca2e6010d9e2 839 uint8_t const i = Q_ROM_BYTE(QF_div8Lkup[p]);
QL 9:ca2e6010d9e2 840
QL 9:ca2e6010d9e2 841 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 842 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 843
QL 9:ca2e6010d9e2 844 QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_SUBSCRIBE, QS::aoObj_, this)
QL 9:ca2e6010d9e2 845 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 846 QS_SIG_(sig); // the signal of this event
QL 9:ca2e6010d9e2 847 QS_OBJ_(this); // this active object
QL 9:ca2e6010d9e2 848 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 849 // set the priority bit
QL 9:ca2e6010d9e2 850 QF_PTR_AT_(QF_subscrList_, sig).m_bits[i] |= Q_ROM_BYTE(QF_pwr2Lkup[p]);
QL 9:ca2e6010d9e2 851 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 852 }
QL 9:ca2e6010d9e2 853
QL 9:ca2e6010d9e2 854 QP_END_
QL 9:ca2e6010d9e2 855
QL 9:ca2e6010d9e2 856 // "qa_usub.cpp" =============================================================
QL 9:ca2e6010d9e2 857 /// \brief QActive::unsubscribe() implementation.
QL 9:ca2e6010d9e2 858
QL 9:ca2e6010d9e2 859 QP_BEGIN_
QL 9:ca2e6010d9e2 860
QL 9:ca2e6010d9e2 861 //............................................................................
QL 9:ca2e6010d9e2 862 void QActive::unsubscribe(enum_t const sig) const {
QL 9:ca2e6010d9e2 863 uint8_t p = m_prio;
QL 9:ca2e6010d9e2 864 Q_REQUIRE((Q_USER_SIG <= sig)
QL 9:ca2e6010d9e2 865 && (sig < QF_maxSignal_)
QL 9:ca2e6010d9e2 866 && (u8_0 < p) && (p <= static_cast<uint8_t>(QF_MAX_ACTIVE))
QL 9:ca2e6010d9e2 867 && (QF::active_[p] == this));
QL 9:ca2e6010d9e2 868
QL 9:ca2e6010d9e2 869 uint8_t const i = Q_ROM_BYTE(QF_div8Lkup[p]);
QL 9:ca2e6010d9e2 870
QL 9:ca2e6010d9e2 871 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 872 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 873
QL 9:ca2e6010d9e2 874 QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_UNSUBSCRIBE, QS::aoObj_, this)
QL 9:ca2e6010d9e2 875 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 876 QS_SIG_(sig); // the signal of this event
QL 9:ca2e6010d9e2 877 QS_OBJ_(this); // this active object
QL 9:ca2e6010d9e2 878 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 879 // clear the priority bit
QL 9:ca2e6010d9e2 880 QF_PTR_AT_(QF_subscrList_,sig).m_bits[i] &= Q_ROM_BYTE(QF_invPwr2Lkup[p]);
QL 9:ca2e6010d9e2 881 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 882 }
QL 9:ca2e6010d9e2 883
QL 9:ca2e6010d9e2 884 QP_END_
QL 9:ca2e6010d9e2 885
QL 9:ca2e6010d9e2 886 // "qa_usuba.cpp" ============================================================
QL 9:ca2e6010d9e2 887 /// \brief QActive::unsubscribeAll() implementation.
QL 9:ca2e6010d9e2 888
QL 9:ca2e6010d9e2 889 QP_BEGIN_
QL 9:ca2e6010d9e2 890
QL 9:ca2e6010d9e2 891 //............................................................................
QL 9:ca2e6010d9e2 892 void QActive::unsubscribeAll(void) const {
QL 9:ca2e6010d9e2 893 uint8_t const p = m_prio;
QL 9:ca2e6010d9e2 894 Q_REQUIRE((u8_0 < p) && (p <= static_cast<uint8_t>(QF_MAX_ACTIVE))
QL 9:ca2e6010d9e2 895 && (QF::active_[p] == this));
QL 9:ca2e6010d9e2 896
QL 9:ca2e6010d9e2 897 uint8_t const i = Q_ROM_BYTE(QF_div8Lkup[p]);
QL 9:ca2e6010d9e2 898
QL 9:ca2e6010d9e2 899 enum_t sig;
QL 9:ca2e6010d9e2 900 for (sig = Q_USER_SIG; sig < QF_maxSignal_; ++sig) {
QL 9:ca2e6010d9e2 901 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 902 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 903 if ((QF_PTR_AT_(QF_subscrList_, sig).m_bits[i]
QL 9:ca2e6010d9e2 904 & Q_ROM_BYTE(QF_pwr2Lkup[p])) != u8_0)
QL 9:ca2e6010d9e2 905 {
QL 9:ca2e6010d9e2 906
QL 9:ca2e6010d9e2 907 QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_UNSUBSCRIBE, QS::aoObj_, this)
QL 9:ca2e6010d9e2 908 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 909 QS_SIG_(sig); // the signal of this event
QL 9:ca2e6010d9e2 910 QS_OBJ_(this); // this active object
QL 9:ca2e6010d9e2 911 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 912 // clear the priority bit
QL 9:ca2e6010d9e2 913 QF_PTR_AT_(QF_subscrList_, sig).m_bits[i] &=
QL 9:ca2e6010d9e2 914 Q_ROM_BYTE(QF_invPwr2Lkup[p]);
QL 9:ca2e6010d9e2 915 }
QL 9:ca2e6010d9e2 916 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 917 }
QL 9:ca2e6010d9e2 918 }
QL 9:ca2e6010d9e2 919
QL 9:ca2e6010d9e2 920 QP_END_
QL 9:ca2e6010d9e2 921
QL 9:ca2e6010d9e2 922 // "qeq_fifo.cpp" ============================================================
QL 9:ca2e6010d9e2 923 /// \brief QEQueue::postFIFO() implementation.
QL 9:ca2e6010d9e2 924
QL 9:ca2e6010d9e2 925 QP_BEGIN_
QL 9:ca2e6010d9e2 926
QL 9:ca2e6010d9e2 927 //............................................................................
QL 9:ca2e6010d9e2 928 void QEQueue::postFIFO(QEvt const * const e) {
QL 9:ca2e6010d9e2 929 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 930 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 931
QL 9:ca2e6010d9e2 932 QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_POST_FIFO, QS::eqObj_, this)
QL 9:ca2e6010d9e2 933 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 934 QS_SIG_(e->sig); // the signal of this event
QL 9:ca2e6010d9e2 935 QS_OBJ_(this); // this queue object
QL 9:ca2e6010d9e2 936 QS_U8_(QF_EVT_POOL_ID_(e)); // the pool Id of the event
QL 9:ca2e6010d9e2 937 QS_U8_(QF_EVT_REF_CTR_(e)); // the ref count of the event
QL 9:ca2e6010d9e2 938 QS_EQC_(m_nFree); // number of free entries
QL 9:ca2e6010d9e2 939 QS_EQC_(m_nMin); // min number of free entries
QL 9:ca2e6010d9e2 940 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 941
QL 9:ca2e6010d9e2 942 if (QF_EVT_POOL_ID_(e) != u8_0) { // is it a dynamic event?
QL 9:ca2e6010d9e2 943 QF_EVT_REF_CTR_INC_(e); // increment the reference counter
QL 9:ca2e6010d9e2 944 }
QL 9:ca2e6010d9e2 945
QL 9:ca2e6010d9e2 946 if (m_frontEvt == null_evt) { // is the queue empty?
QL 9:ca2e6010d9e2 947 m_frontEvt = e; // deliver event directly
QL 9:ca2e6010d9e2 948 }
QL 9:ca2e6010d9e2 949 else { // queue is not empty, leave event in the ring-buffer
QL 9:ca2e6010d9e2 950 // the queue must be able to accept the event (cannot overflow)
QL 9:ca2e6010d9e2 951 Q_ASSERT(m_nFree != static_cast<QEQueueCtr>(0));
QL 9:ca2e6010d9e2 952
QL 9:ca2e6010d9e2 953 QF_PTR_AT_(m_ring, m_head) = e; // insert event into the buffer (FIFO)
QL 9:ca2e6010d9e2 954 if (m_head == static_cast<QEQueueCtr>(0)) { // need to wrap?
QL 9:ca2e6010d9e2 955 m_head = m_end; // wrap around
QL 9:ca2e6010d9e2 956 }
QL 9:ca2e6010d9e2 957 --m_head;
QL 9:ca2e6010d9e2 958
QL 9:ca2e6010d9e2 959 --m_nFree; // update number of free events
QL 9:ca2e6010d9e2 960 if (m_nMin > m_nFree) {
QL 9:ca2e6010d9e2 961 m_nMin = m_nFree; // update minimum so far
QL 9:ca2e6010d9e2 962 }
QL 9:ca2e6010d9e2 963 }
QL 9:ca2e6010d9e2 964 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 965 }
QL 9:ca2e6010d9e2 966
QL 9:ca2e6010d9e2 967 QP_END_
QL 9:ca2e6010d9e2 968
QL 9:ca2e6010d9e2 969 // "qeq_get.cpp" =============================================================
QL 9:ca2e6010d9e2 970 /// \brief QEQueue::get() implementation.
QL 9:ca2e6010d9e2 971
QL 9:ca2e6010d9e2 972 QP_BEGIN_
QL 9:ca2e6010d9e2 973
QL 9:ca2e6010d9e2 974 //............................................................................
QL 9:ca2e6010d9e2 975 QEvt const *QEQueue::get(void) {
QL 9:ca2e6010d9e2 976 QEvt const *e;
QL 9:ca2e6010d9e2 977 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 978
QL 9:ca2e6010d9e2 979 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 980 if (m_frontEvt == null_evt) { // is the queue empty?
QL 9:ca2e6010d9e2 981 e = null_evt; // no event available at this time
QL 9:ca2e6010d9e2 982 }
QL 9:ca2e6010d9e2 983 else {
QL 9:ca2e6010d9e2 984 e = m_frontEvt;
QL 9:ca2e6010d9e2 985
QL 9:ca2e6010d9e2 986 if (m_nFree != m_end) { // any events in the the ring buffer?
QL 9:ca2e6010d9e2 987 m_frontEvt = QF_PTR_AT_(m_ring, m_tail); // remove from the tail
QL 9:ca2e6010d9e2 988 if (m_tail == static_cast<QEQueueCtr>(0)) { // need to wrap?
QL 9:ca2e6010d9e2 989 m_tail = m_end; // wrap around
QL 9:ca2e6010d9e2 990 }
QL 9:ca2e6010d9e2 991 --m_tail;
QL 9:ca2e6010d9e2 992
QL 9:ca2e6010d9e2 993 ++m_nFree; // one more free event in the ring buffer
QL 9:ca2e6010d9e2 994
QL 9:ca2e6010d9e2 995 QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_GET, QS::eqObj_, this)
QL 9:ca2e6010d9e2 996 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 997 QS_SIG_(e->sig); // the signal of this event
QL 9:ca2e6010d9e2 998 QS_OBJ_(this); // this queue object
QL 9:ca2e6010d9e2 999 QS_U8_(QF_EVT_POOL_ID_(e)); // the pool Id of the event
QL 9:ca2e6010d9e2 1000 QS_U8_(QF_EVT_REF_CTR_(e)); // the ref count of the event
QL 9:ca2e6010d9e2 1001 QS_EQC_(m_nFree); // number of free entries
QL 9:ca2e6010d9e2 1002 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1003 }
QL 9:ca2e6010d9e2 1004 else {
QL 9:ca2e6010d9e2 1005 m_frontEvt = null_evt; // the queue becomes empty
QL 9:ca2e6010d9e2 1006
QL 9:ca2e6010d9e2 1007 QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_GET_LAST, QS::eqObj_, this)
QL 9:ca2e6010d9e2 1008 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 1009 QS_SIG_(e->sig); // the signal of this event
QL 9:ca2e6010d9e2 1010 QS_OBJ_(this); // this queue object
QL 9:ca2e6010d9e2 1011 QS_U8_(QF_EVT_POOL_ID_(e)); // the pool Id of the event
QL 9:ca2e6010d9e2 1012 QS_U8_(QF_EVT_REF_CTR_(e)); // the ref count of the event
QL 9:ca2e6010d9e2 1013 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1014 }
QL 9:ca2e6010d9e2 1015 }
QL 9:ca2e6010d9e2 1016 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 1017 return e;
QL 9:ca2e6010d9e2 1018 }
QL 9:ca2e6010d9e2 1019
QL 9:ca2e6010d9e2 1020 QP_END_
QL 9:ca2e6010d9e2 1021
QL 9:ca2e6010d9e2 1022 // "qeq_init.cpp" ============================================================
QL 9:ca2e6010d9e2 1023 /// \brief QEQueue::init() implementation.
QL 9:ca2e6010d9e2 1024
QL 9:ca2e6010d9e2 1025 QP_BEGIN_
QL 9:ca2e6010d9e2 1026
QL 9:ca2e6010d9e2 1027 //............................................................................
QL 9:ca2e6010d9e2 1028 void QEQueue::init(QEvt const *qSto[], QEQueueCtr const qLen) {
QL 9:ca2e6010d9e2 1029 m_frontEvt = null_evt; // no events in the queue
QL 9:ca2e6010d9e2 1030 m_ring = &qSto[0];
QL 9:ca2e6010d9e2 1031 m_end = qLen;
QL 9:ca2e6010d9e2 1032 m_head = static_cast<QEQueueCtr>(0);
QL 9:ca2e6010d9e2 1033 m_tail = static_cast<QEQueueCtr>(0);
QL 9:ca2e6010d9e2 1034 m_nFree = qLen;
QL 9:ca2e6010d9e2 1035 m_nMin = qLen;
QL 9:ca2e6010d9e2 1036
QL 9:ca2e6010d9e2 1037 QS_CRIT_STAT_
QL 9:ca2e6010d9e2 1038 QS_BEGIN_(QS_QF_EQUEUE_INIT, QS::eqObj_, this)
QL 9:ca2e6010d9e2 1039 QS_OBJ_(qSto); // this QEQueue object
QL 9:ca2e6010d9e2 1040 QS_EQC_(qLen); // the length of the queue
QL 9:ca2e6010d9e2 1041 QS_END_()
QL 9:ca2e6010d9e2 1042 }
QL 9:ca2e6010d9e2 1043
QL 9:ca2e6010d9e2 1044 QP_END_
QL 9:ca2e6010d9e2 1045
QL 9:ca2e6010d9e2 1046 // "qeq_lifo.cpp" ============================================================
QL 9:ca2e6010d9e2 1047 /// \brief QEQueue::postLIFO() implementation.
QL 9:ca2e6010d9e2 1048
QL 9:ca2e6010d9e2 1049 QP_BEGIN_
QL 9:ca2e6010d9e2 1050
QL 9:ca2e6010d9e2 1051 //............................................................................
QL 9:ca2e6010d9e2 1052 void QEQueue::postLIFO(QEvt const * const e) {
QL 9:ca2e6010d9e2 1053 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 1054 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 1055
QL 9:ca2e6010d9e2 1056 QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_POST_LIFO, QS::eqObj_, this)
QL 9:ca2e6010d9e2 1057 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 1058 QS_SIG_(e->sig); // the signal of this event
QL 9:ca2e6010d9e2 1059 QS_OBJ_(this); // this queue object
QL 9:ca2e6010d9e2 1060 QS_U8_(QF_EVT_POOL_ID_(e)); // the pool Id of the event
QL 9:ca2e6010d9e2 1061 QS_U8_(QF_EVT_REF_CTR_(e)); // the ref count of the event
QL 9:ca2e6010d9e2 1062 QS_EQC_(m_nFree); // number of free entries
QL 9:ca2e6010d9e2 1063 QS_EQC_(m_nMin); // min number of free entries
QL 9:ca2e6010d9e2 1064 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1065
QL 9:ca2e6010d9e2 1066 if (QF_EVT_POOL_ID_(e) != u8_0) { // is it a dynamic event?
QL 9:ca2e6010d9e2 1067 QF_EVT_REF_CTR_INC_(e); // increment the reference counter
QL 9:ca2e6010d9e2 1068 }
QL 9:ca2e6010d9e2 1069
QL 9:ca2e6010d9e2 1070 if (m_frontEvt != null_evt) { // is the queue not empty?
QL 9:ca2e6010d9e2 1071 // the queue must be able to accept the event (cannot overflow)
QL 9:ca2e6010d9e2 1072 Q_ASSERT(m_nFree != static_cast<QEQueueCtr>(0));
QL 9:ca2e6010d9e2 1073
QL 9:ca2e6010d9e2 1074 ++m_tail;
QL 9:ca2e6010d9e2 1075 if (m_tail == m_end) { // need to wrap the tail?
QL 9:ca2e6010d9e2 1076 m_tail = static_cast<QEQueueCtr>(0); // wrap around
QL 9:ca2e6010d9e2 1077 }
QL 9:ca2e6010d9e2 1078
QL 9:ca2e6010d9e2 1079 QF_PTR_AT_(m_ring, m_tail) = m_frontEvt; // buffer the old front evt
QL 9:ca2e6010d9e2 1080
QL 9:ca2e6010d9e2 1081 --m_nFree; // update number of free events
QL 9:ca2e6010d9e2 1082 if (m_nMin > m_nFree) {
QL 9:ca2e6010d9e2 1083 m_nMin = m_nFree; // update minimum so far
QL 9:ca2e6010d9e2 1084 }
QL 9:ca2e6010d9e2 1085 }
QL 9:ca2e6010d9e2 1086
QL 9:ca2e6010d9e2 1087 m_frontEvt = e; // stick the new event to the front
QL 9:ca2e6010d9e2 1088
QL 9:ca2e6010d9e2 1089 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 1090 }
QL 9:ca2e6010d9e2 1091
QL 9:ca2e6010d9e2 1092 QP_END_
QL 9:ca2e6010d9e2 1093
QL 9:ca2e6010d9e2 1094 // "qf_act.cpp" ==============================================================
QL 9:ca2e6010d9e2 1095 /// \brief QF::active_[], QF::getVersion(), and QF::add_()/QF::remove_()
QL 9:ca2e6010d9e2 1096 /// implementation.
QL 9:ca2e6010d9e2 1097
QL 9:ca2e6010d9e2 1098 QP_BEGIN_
QL 9:ca2e6010d9e2 1099
QL 9:ca2e6010d9e2 1100 // public objects ------------------------------------------------------------
QL 9:ca2e6010d9e2 1101 QActive *QF::active_[QF_MAX_ACTIVE + 1]; // to be used by QF ports only
QL 9:ca2e6010d9e2 1102 uint8_t QF_intLockNest_; // interrupt-lock nesting level
QL 9:ca2e6010d9e2 1103
QL 9:ca2e6010d9e2 1104 //............................................................................
QL 9:ca2e6010d9e2 1105 char_t const Q_ROM * Q_ROM_VAR QF::getVersion(void) {
QL 9:ca2e6010d9e2 1106 uint8_t const u8_zero = static_cast<uint8_t>('0');
QL 9:ca2e6010d9e2 1107 static char_t const Q_ROM Q_ROM_VAR version[] = {
QL 9:ca2e6010d9e2 1108 static_cast<char_t>(((QP_VERSION >> 12) & 0xFU) + u8_zero),
QL 9:ca2e6010d9e2 1109 static_cast<char_t>('.'),
QL 9:ca2e6010d9e2 1110 static_cast<char_t>(((QP_VERSION >> 8) & 0xFU) + u8_zero),
QL 9:ca2e6010d9e2 1111 static_cast<char_t>('.'),
QL 9:ca2e6010d9e2 1112 static_cast<char_t>(((QP_VERSION >> 4) & 0xFU) + u8_zero),
QL 9:ca2e6010d9e2 1113 static_cast<char_t>((QP_VERSION & 0xFU) + u8_zero),
QL 9:ca2e6010d9e2 1114 static_cast<char_t>('\0')
QL 9:ca2e6010d9e2 1115 };
QL 9:ca2e6010d9e2 1116 return version;
QL 9:ca2e6010d9e2 1117 }
QL 9:ca2e6010d9e2 1118 //............................................................................
QL 9:ca2e6010d9e2 1119 void QF::add_(QActive * const a) {
QL 9:ca2e6010d9e2 1120 uint8_t p = a->m_prio;
QL 9:ca2e6010d9e2 1121
QL 9:ca2e6010d9e2 1122 Q_REQUIRE((u8_0 < p) && (p <= static_cast<uint8_t>(QF_MAX_ACTIVE))
QL 9:ca2e6010d9e2 1123 && (active_[p] == static_cast<QActive *>(0)));
QL 9:ca2e6010d9e2 1124
QL 9:ca2e6010d9e2 1125 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 1126 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 1127
QL 9:ca2e6010d9e2 1128 active_[p] = a; // registger the active object at this priority
QL 9:ca2e6010d9e2 1129
QL 9:ca2e6010d9e2 1130 QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_ADD, QS::aoObj_, a)
QL 9:ca2e6010d9e2 1131 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 1132 QS_OBJ_(a); // the active object
QL 9:ca2e6010d9e2 1133 QS_U8_(p); // the priority of the active object
QL 9:ca2e6010d9e2 1134 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1135
QL 9:ca2e6010d9e2 1136 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 1137 }
QL 9:ca2e6010d9e2 1138 //............................................................................
QL 9:ca2e6010d9e2 1139 void QF::remove_(QActive const * const a) {
QL 9:ca2e6010d9e2 1140 uint8_t p = a->m_prio;
QL 9:ca2e6010d9e2 1141
QL 9:ca2e6010d9e2 1142 Q_REQUIRE((u8_0 < p) && (p <= static_cast<uint8_t>(QF_MAX_ACTIVE))
QL 9:ca2e6010d9e2 1143 && (active_[p] == a));
QL 9:ca2e6010d9e2 1144
QL 9:ca2e6010d9e2 1145 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 1146 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 1147
QL 9:ca2e6010d9e2 1148 active_[p] = static_cast<QActive *>(0); // free-up the priority level
QL 9:ca2e6010d9e2 1149
QL 9:ca2e6010d9e2 1150 QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_REMOVE, QS::aoObj_, a)
QL 9:ca2e6010d9e2 1151 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 1152 QS_OBJ_(a); // the active object
QL 9:ca2e6010d9e2 1153 QS_U8_(p); // the priority of the active object
QL 9:ca2e6010d9e2 1154 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1155
QL 9:ca2e6010d9e2 1156 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 1157 }
QL 9:ca2e6010d9e2 1158
QL 9:ca2e6010d9e2 1159 QP_END_
QL 9:ca2e6010d9e2 1160
QL 9:ca2e6010d9e2 1161
QL 9:ca2e6010d9e2 1162 // "qf_gc.cpp" ===============================================================
QL 9:ca2e6010d9e2 1163 /// \brief QF::gc() implementation.
QL 9:ca2e6010d9e2 1164
QL 9:ca2e6010d9e2 1165 QP_BEGIN_
QL 9:ca2e6010d9e2 1166
QL 9:ca2e6010d9e2 1167 //............................................................................
QL 9:ca2e6010d9e2 1168 void QF::gc(QEvt const * const e) {
QL 9:ca2e6010d9e2 1169 if (QF_EVT_POOL_ID_(e) != u8_0) { // is it a dynamic event?
QL 9:ca2e6010d9e2 1170 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 1171 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 1172
QL 9:ca2e6010d9e2 1173 if (QF_EVT_REF_CTR_(e) > u8_1) { // isn't this the last reference?
QL 9:ca2e6010d9e2 1174 QF_EVT_REF_CTR_DEC_(e); // decrement the ref counter
QL 9:ca2e6010d9e2 1175
QL 9:ca2e6010d9e2 1176 QS_BEGIN_NOCRIT_(QS_QF_GC_ATTEMPT, null_void, null_void)
QL 9:ca2e6010d9e2 1177 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 1178 QS_SIG_(e->sig); // the signal of the event
QL 9:ca2e6010d9e2 1179 QS_U8_(QF_EVT_POOL_ID_(e)); // the pool Id of the event
QL 9:ca2e6010d9e2 1180 QS_U8_(QF_EVT_REF_CTR_(e)); // the ref count of the event
QL 9:ca2e6010d9e2 1181 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1182
QL 9:ca2e6010d9e2 1183 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 1184 }
QL 9:ca2e6010d9e2 1185 else { // this is the last reference to this event, recycle it
QL 9:ca2e6010d9e2 1186 uint8_t idx = static_cast<uint8_t>(QF_EVT_POOL_ID_(e) - u8_1);
QL 9:ca2e6010d9e2 1187
QL 9:ca2e6010d9e2 1188 QS_BEGIN_NOCRIT_(QS_QF_GC, null_void, null_void)
QL 9:ca2e6010d9e2 1189 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 1190 QS_SIG_(e->sig); // the signal of the event
QL 9:ca2e6010d9e2 1191 QS_U8_(QF_EVT_POOL_ID_(e)); // the pool Id of the event
QL 9:ca2e6010d9e2 1192 QS_U8_(QF_EVT_REF_CTR_(e)); // the ref count of the event
QL 9:ca2e6010d9e2 1193 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1194
QL 9:ca2e6010d9e2 1195 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 1196
QL 9:ca2e6010d9e2 1197 Q_ASSERT(idx < QF_maxPool_);
QL 9:ca2e6010d9e2 1198
QL 9:ca2e6010d9e2 1199 #ifdef Q_EVT_VIRTUAL
QL 9:ca2e6010d9e2 1200 QF_EVT_CONST_CAST_(e)->~QEvt(); // xtor, cast 'const' away,
QL 9:ca2e6010d9e2 1201 // which is legitimate, because it's a pool event
QL 9:ca2e6010d9e2 1202 #endif
QL 9:ca2e6010d9e2 1203 // cast 'const' away, which is OK, because it's a pool event
QL 9:ca2e6010d9e2 1204 QF_EPOOL_PUT_(QF_pool_[idx], QF_EVT_CONST_CAST_(e));
QL 9:ca2e6010d9e2 1205 }
QL 9:ca2e6010d9e2 1206 }
QL 9:ca2e6010d9e2 1207 }
QL 9:ca2e6010d9e2 1208
QL 9:ca2e6010d9e2 1209 QP_END_
QL 9:ca2e6010d9e2 1210
QL 9:ca2e6010d9e2 1211 // "qf_log2.cpp" =============================================================
QL 9:ca2e6010d9e2 1212 /// \brief QF_log2Lkup[] implementation.
QL 9:ca2e6010d9e2 1213
QL 9:ca2e6010d9e2 1214 QP_BEGIN_
QL 9:ca2e6010d9e2 1215
QL 9:ca2e6010d9e2 1216 // Global objects ------------------------------------------------------------
QL 9:ca2e6010d9e2 1217 uint8_t const Q_ROM Q_ROM_VAR QF_log2Lkup[256] = {
QL 9:ca2e6010d9e2 1218 static_cast<uint8_t>(0),
QL 9:ca2e6010d9e2 1219 static_cast<uint8_t>(1),
QL 9:ca2e6010d9e2 1220 static_cast<uint8_t>(2), static_cast<uint8_t>(2),
QL 9:ca2e6010d9e2 1221 static_cast<uint8_t>(3), static_cast<uint8_t>(3), static_cast<uint8_t>(3),
QL 9:ca2e6010d9e2 1222 static_cast<uint8_t>(3),
QL 9:ca2e6010d9e2 1223 static_cast<uint8_t>(4), static_cast<uint8_t>(4), static_cast<uint8_t>(4),
QL 9:ca2e6010d9e2 1224 static_cast<uint8_t>(4), static_cast<uint8_t>(4), static_cast<uint8_t>(4),
QL 9:ca2e6010d9e2 1225 static_cast<uint8_t>(4), static_cast<uint8_t>(4),
QL 9:ca2e6010d9e2 1226 static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
QL 9:ca2e6010d9e2 1227 static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
QL 9:ca2e6010d9e2 1228 static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
QL 9:ca2e6010d9e2 1229 static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
QL 9:ca2e6010d9e2 1230 static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
QL 9:ca2e6010d9e2 1231 static_cast<uint8_t>(5),
QL 9:ca2e6010d9e2 1232 static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
QL 9:ca2e6010d9e2 1233 static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
QL 9:ca2e6010d9e2 1234 static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
QL 9:ca2e6010d9e2 1235 static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
QL 9:ca2e6010d9e2 1236 static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
QL 9:ca2e6010d9e2 1237 static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
QL 9:ca2e6010d9e2 1238 static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
QL 9:ca2e6010d9e2 1239 static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
QL 9:ca2e6010d9e2 1240 static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
QL 9:ca2e6010d9e2 1241 static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
QL 9:ca2e6010d9e2 1242 static_cast<uint8_t>(6), static_cast<uint8_t>(6),
QL 9:ca2e6010d9e2 1243 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1244 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1245 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1246 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1247 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1248 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1249 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1250 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1251 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1252 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1253 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1254 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1255 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1256 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1257 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1258 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1259 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1260 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1261 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1262 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1263 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1264 static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1265 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1266 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1267 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1268 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1269 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1270 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1271 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1272 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1273 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1274 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1275 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1276 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1277 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1278 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1279 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1280 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1281 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1282 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1283 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1284 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1285 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1286 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1287 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1288 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1289 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1290 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1291 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1292 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1293 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1294 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1295 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1296 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1297 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1298 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1299 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1300 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1301 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1302 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1303 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1304 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1305 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1306 static_cast<uint8_t>(8), static_cast<uint8_t>(8), static_cast<uint8_t>(8),
QL 9:ca2e6010d9e2 1307 static_cast<uint8_t>(8), static_cast<uint8_t>(8)
QL 9:ca2e6010d9e2 1308 };
QL 9:ca2e6010d9e2 1309
QL 9:ca2e6010d9e2 1310 QP_END_
QL 9:ca2e6010d9e2 1311
QL 9:ca2e6010d9e2 1312 // "qf_new.cpp" ==============================================================
QL 9:ca2e6010d9e2 1313 /// \brief QF::new_() implementation.
QL 9:ca2e6010d9e2 1314
QL 9:ca2e6010d9e2 1315 QP_BEGIN_
QL 9:ca2e6010d9e2 1316
QL 9:ca2e6010d9e2 1317 //............................................................................
QL 9:ca2e6010d9e2 1318 QEvt *QF::new_(QEvtSize const evtSize, enum_t const sig) {
QL 9:ca2e6010d9e2 1319 // find the pool id that fits the requested event size ...
QL 9:ca2e6010d9e2 1320 uint8_t idx = u8_0;
QL 9:ca2e6010d9e2 1321 while (evtSize
QL 9:ca2e6010d9e2 1322 > static_cast<QEvtSize>(QF_EPOOL_EVENT_SIZE_(QF_pool_[idx])))
QL 9:ca2e6010d9e2 1323 {
QL 9:ca2e6010d9e2 1324 ++idx;
QL 9:ca2e6010d9e2 1325 Q_ASSERT(idx < QF_maxPool_); // cannot run out of registered pools
QL 9:ca2e6010d9e2 1326 }
QL 9:ca2e6010d9e2 1327
QL 9:ca2e6010d9e2 1328 QS_CRIT_STAT_
QL 9:ca2e6010d9e2 1329 QS_BEGIN_(QS_QF_NEW, null_void, null_void)
QL 9:ca2e6010d9e2 1330 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 1331 QS_EVS_(evtSize); // the size of the event
QL 9:ca2e6010d9e2 1332 QS_SIG_(static_cast<QSignal>(sig)); // the signal of the event
QL 9:ca2e6010d9e2 1333 QS_END_()
QL 9:ca2e6010d9e2 1334
QL 9:ca2e6010d9e2 1335 QEvt *e;
QL 9:ca2e6010d9e2 1336 QF_EPOOL_GET_(QF_pool_[idx], e);
QL 9:ca2e6010d9e2 1337 Q_ASSERT(e != static_cast<QEvt *>(0));// pool must not run out of events
QL 9:ca2e6010d9e2 1338
QL 9:ca2e6010d9e2 1339 e->sig = static_cast<QSignal>(sig); // set signal for this event
QL 9:ca2e6010d9e2 1340 e->poolId_ = static_cast<uint8_t>(idx + u8_1); // store pool ID in the evt
QL 9:ca2e6010d9e2 1341 e->refCtr_ = u8_0; // set the reference counter to 0
QL 9:ca2e6010d9e2 1342
QL 9:ca2e6010d9e2 1343 return e;
QL 9:ca2e6010d9e2 1344 }
QL 9:ca2e6010d9e2 1345
QL 9:ca2e6010d9e2 1346 QP_END_
QL 9:ca2e6010d9e2 1347
QL 9:ca2e6010d9e2 1348 // "qf_pool.cpp" =============================================================
QL 9:ca2e6010d9e2 1349 /// \brief QF_pool_[] and QF_maxPool_ definition, QF::poolInit()
QL 9:ca2e6010d9e2 1350 /// implementation.
QL 9:ca2e6010d9e2 1351
QL 9:ca2e6010d9e2 1352 QP_BEGIN_
QL 9:ca2e6010d9e2 1353
QL 9:ca2e6010d9e2 1354 // Package-scope objects -----------------------------------------------------
QL 9:ca2e6010d9e2 1355 QF_EPOOL_TYPE_ QF_pool_[QF_MAX_EPOOL]; // allocate the event pools
QL 9:ca2e6010d9e2 1356 uint8_t QF_maxPool_; // number of initialized event pools
QL 9:ca2e6010d9e2 1357
QL 9:ca2e6010d9e2 1358 //............................................................................
QL 9:ca2e6010d9e2 1359 void QF::poolInit(void * const poolSto,
QL 9:ca2e6010d9e2 1360 uint32_t const poolSize, uint32_t const evtSize)
QL 9:ca2e6010d9e2 1361 {
QL 9:ca2e6010d9e2 1362 // cannot exceed the number of available memory pools
QL 9:ca2e6010d9e2 1363 Q_REQUIRE(QF_maxPool_ < static_cast<uint8_t>(Q_DIM(QF_pool_)));
QL 9:ca2e6010d9e2 1364 // please initialize event pools in ascending order of evtSize:
QL 9:ca2e6010d9e2 1365 Q_REQUIRE((QF_maxPool_ == u8_0)
QL 9:ca2e6010d9e2 1366 || (QF_EPOOL_EVENT_SIZE_(QF_pool_[QF_maxPool_ - u8_1])
QL 9:ca2e6010d9e2 1367 < evtSize));
QL 9:ca2e6010d9e2 1368 QF_EPOOL_INIT_(QF_pool_[QF_maxPool_], poolSto, poolSize, evtSize);
QL 9:ca2e6010d9e2 1369 ++QF_maxPool_; // one more pool
QL 9:ca2e6010d9e2 1370 }
QL 9:ca2e6010d9e2 1371
QL 9:ca2e6010d9e2 1372 QP_END_
QL 9:ca2e6010d9e2 1373
QL 9:ca2e6010d9e2 1374
QL 9:ca2e6010d9e2 1375 // "qf_psini.cpp" ============================================================
QL 9:ca2e6010d9e2 1376 /// \brief QF_subscrList_ and QF_maxSignal_ definition, QF::psInit()
QL 9:ca2e6010d9e2 1377 /// implementation.
QL 9:ca2e6010d9e2 1378
QL 9:ca2e6010d9e2 1379 QP_BEGIN_
QL 9:ca2e6010d9e2 1380
QL 9:ca2e6010d9e2 1381 // Package-scope objects -----------------------------------------------------
QL 9:ca2e6010d9e2 1382 QSubscrList *QF_subscrList_;
QL 9:ca2e6010d9e2 1383 enum_t QF_maxSignal_;
QL 9:ca2e6010d9e2 1384
QL 9:ca2e6010d9e2 1385 //............................................................................
QL 9:ca2e6010d9e2 1386 void QF::psInit(QSubscrList * const subscrSto, uint32_t const maxSignal) {
QL 9:ca2e6010d9e2 1387 QF_subscrList_ = subscrSto;
QL 9:ca2e6010d9e2 1388 QF_maxSignal_ = static_cast<enum_t>(maxSignal);
QL 9:ca2e6010d9e2 1389 }
QL 9:ca2e6010d9e2 1390
QL 9:ca2e6010d9e2 1391 QP_END_
QL 9:ca2e6010d9e2 1392
QL 9:ca2e6010d9e2 1393 // "qf_pspub.cpp" ============================================================
QL 9:ca2e6010d9e2 1394 /// \brief QF::publish() implementation.
QL 9:ca2e6010d9e2 1395
QL 9:ca2e6010d9e2 1396 QP_BEGIN_
QL 9:ca2e6010d9e2 1397
QL 9:ca2e6010d9e2 1398 //............................................................................
QL 9:ca2e6010d9e2 1399 #ifndef Q_SPY
QL 9:ca2e6010d9e2 1400 void QF::publish(QEvt const * const e) {
QL 9:ca2e6010d9e2 1401 #else
QL 9:ca2e6010d9e2 1402 void QF::publish(QEvt const * const e, void const * const sender) {
QL 9:ca2e6010d9e2 1403 #endif
QL 9:ca2e6010d9e2 1404 // make sure that the published signal is within the configured range
QL 9:ca2e6010d9e2 1405 Q_REQUIRE(static_cast<enum_t>(e->sig) < QF_maxSignal_);
QL 9:ca2e6010d9e2 1406
QL 9:ca2e6010d9e2 1407 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 1408 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 1409
QL 9:ca2e6010d9e2 1410 QS_BEGIN_NOCRIT_(QS_QF_PUBLISH, null_void, null_void)
QL 9:ca2e6010d9e2 1411 QS_TIME_(); // the timestamp
QL 9:ca2e6010d9e2 1412 QS_OBJ_(sender); // the sender object
QL 9:ca2e6010d9e2 1413 QS_SIG_(e->sig); // the signal of the event
QL 9:ca2e6010d9e2 1414 QS_U8_(QF_EVT_POOL_ID_(e)); // the pool Id of the event
QL 9:ca2e6010d9e2 1415 QS_U8_(QF_EVT_REF_CTR_(e)); // the ref count of the event
QL 9:ca2e6010d9e2 1416 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1417
QL 9:ca2e6010d9e2 1418 if (QF_EVT_POOL_ID_(e) != u8_0) { // is it a dynamic event?
QL 9:ca2e6010d9e2 1419 QF_EVT_REF_CTR_INC_(e); // increment the reference counter, NOTE01
QL 9:ca2e6010d9e2 1420 }
QL 9:ca2e6010d9e2 1421 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 1422
QL 9:ca2e6010d9e2 1423 #if (QF_MAX_ACTIVE <= 8)
QL 9:ca2e6010d9e2 1424 uint8_t tmp = QF_PTR_AT_(QF_subscrList_, e->sig).m_bits[0];
QL 9:ca2e6010d9e2 1425 while (tmp != u8_0) {
QL 9:ca2e6010d9e2 1426 uint8_t p = Q_ROM_BYTE(QF_log2Lkup[tmp]);
QL 9:ca2e6010d9e2 1427 tmp &= Q_ROM_BYTE(QF_invPwr2Lkup[p]); // clear the subscriber bit
QL 9:ca2e6010d9e2 1428 Q_ASSERT(active_[p] != static_cast<QActive *>(0));//must be registered
QL 9:ca2e6010d9e2 1429
QL 9:ca2e6010d9e2 1430 // POST() asserts internally if the queue overflows
QL 9:ca2e6010d9e2 1431 active_[p]->POST(e, sender);
QL 9:ca2e6010d9e2 1432 }
QL 9:ca2e6010d9e2 1433 #else
QL 9:ca2e6010d9e2 1434 // number of bytes in the list
QL 9:ca2e6010d9e2 1435 uint8_t i = QF_SUBSCR_LIST_SIZE;
QL 9:ca2e6010d9e2 1436 do { // go through all bytes in the subsciption list
QL 9:ca2e6010d9e2 1437 --i;
QL 9:ca2e6010d9e2 1438 uint8_t tmp = QF_PTR_AT_(QF_subscrList_, e->sig).m_bits[i];
QL 9:ca2e6010d9e2 1439 while (tmp != u8_0) {
QL 9:ca2e6010d9e2 1440 uint8_t p = Q_ROM_BYTE(QF_log2Lkup[tmp]);
QL 9:ca2e6010d9e2 1441 tmp &= Q_ROM_BYTE(QF_invPwr2Lkup[p]); // clear the subscriber bit
QL 9:ca2e6010d9e2 1442 // adjust the priority
QL 9:ca2e6010d9e2 1443 p = static_cast<uint8_t>(p + static_cast<uint8_t>(i << 3));
QL 9:ca2e6010d9e2 1444 Q_ASSERT(active_[p] != static_cast<QActive *>(0)); // registered
QL 9:ca2e6010d9e2 1445
QL 9:ca2e6010d9e2 1446 // POST() asserts internally if the queue overflows
QL 9:ca2e6010d9e2 1447 active_[p]->POST(e, sender);
QL 9:ca2e6010d9e2 1448 }
QL 9:ca2e6010d9e2 1449 } while (i != u8_0);
QL 9:ca2e6010d9e2 1450 #endif
QL 9:ca2e6010d9e2 1451
QL 9:ca2e6010d9e2 1452 gc(e); // run the garbage collector, see NOTE01
QL 9:ca2e6010d9e2 1453 }
QL 9:ca2e6010d9e2 1454
QL 9:ca2e6010d9e2 1455 QP_END_
QL 9:ca2e6010d9e2 1456
QL 9:ca2e6010d9e2 1457
QL 9:ca2e6010d9e2 1458 // "qf_pwr2.cpp" =============================================================
QL 9:ca2e6010d9e2 1459 /// \brief QF_pwr2Lkup[], QF_invPwr2Lkup[], and QF_div8Lkup[] definitions.
QL 9:ca2e6010d9e2 1460
QL 9:ca2e6010d9e2 1461 QP_BEGIN_
QL 9:ca2e6010d9e2 1462
QL 9:ca2e6010d9e2 1463 // Global objects ------------------------------------------------------------
QL 9:ca2e6010d9e2 1464 uint8_t const Q_ROM Q_ROM_VAR QF_pwr2Lkup[65] = {
QL 9:ca2e6010d9e2 1465 static_cast<uint8_t>(0x00), // unused location
QL 9:ca2e6010d9e2 1466 static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
QL 9:ca2e6010d9e2 1467 static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
QL 9:ca2e6010d9e2 1468 static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
QL 9:ca2e6010d9e2 1469 static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
QL 9:ca2e6010d9e2 1470 static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
QL 9:ca2e6010d9e2 1471 static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
QL 9:ca2e6010d9e2 1472 static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
QL 9:ca2e6010d9e2 1473 static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
QL 9:ca2e6010d9e2 1474 static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
QL 9:ca2e6010d9e2 1475 static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
QL 9:ca2e6010d9e2 1476 static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
QL 9:ca2e6010d9e2 1477 static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
QL 9:ca2e6010d9e2 1478 static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
QL 9:ca2e6010d9e2 1479 static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
QL 9:ca2e6010d9e2 1480 static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
QL 9:ca2e6010d9e2 1481 static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
QL 9:ca2e6010d9e2 1482 static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
QL 9:ca2e6010d9e2 1483 static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
QL 9:ca2e6010d9e2 1484 static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
QL 9:ca2e6010d9e2 1485 static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
QL 9:ca2e6010d9e2 1486 static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
QL 9:ca2e6010d9e2 1487 static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
QL 9:ca2e6010d9e2 1488 static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
QL 9:ca2e6010d9e2 1489 static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
QL 9:ca2e6010d9e2 1490 static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
QL 9:ca2e6010d9e2 1491 static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
QL 9:ca2e6010d9e2 1492 static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
QL 9:ca2e6010d9e2 1493 static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80),
QL 9:ca2e6010d9e2 1494 static_cast<uint8_t>(0x01), static_cast<uint8_t>(0x02),
QL 9:ca2e6010d9e2 1495 static_cast<uint8_t>(0x04), static_cast<uint8_t>(0x08),
QL 9:ca2e6010d9e2 1496 static_cast<uint8_t>(0x10), static_cast<uint8_t>(0x20),
QL 9:ca2e6010d9e2 1497 static_cast<uint8_t>(0x40), static_cast<uint8_t>(0x80)
QL 9:ca2e6010d9e2 1498 };
QL 9:ca2e6010d9e2 1499
QL 9:ca2e6010d9e2 1500 uint8_t const Q_ROM Q_ROM_VAR QF_invPwr2Lkup[65] = {
QL 9:ca2e6010d9e2 1501 static_cast<uint8_t>(0xFF), // unused location
QL 9:ca2e6010d9e2 1502 static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
QL 9:ca2e6010d9e2 1503 static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
QL 9:ca2e6010d9e2 1504 static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
QL 9:ca2e6010d9e2 1505 static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
QL 9:ca2e6010d9e2 1506 static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
QL 9:ca2e6010d9e2 1507 static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
QL 9:ca2e6010d9e2 1508 static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
QL 9:ca2e6010d9e2 1509 static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
QL 9:ca2e6010d9e2 1510 static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
QL 9:ca2e6010d9e2 1511 static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
QL 9:ca2e6010d9e2 1512 static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
QL 9:ca2e6010d9e2 1513 static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
QL 9:ca2e6010d9e2 1514 static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
QL 9:ca2e6010d9e2 1515 static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
QL 9:ca2e6010d9e2 1516 static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
QL 9:ca2e6010d9e2 1517 static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
QL 9:ca2e6010d9e2 1518 static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
QL 9:ca2e6010d9e2 1519 static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
QL 9:ca2e6010d9e2 1520 static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
QL 9:ca2e6010d9e2 1521 static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
QL 9:ca2e6010d9e2 1522 static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
QL 9:ca2e6010d9e2 1523 static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
QL 9:ca2e6010d9e2 1524 static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
QL 9:ca2e6010d9e2 1525 static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
QL 9:ca2e6010d9e2 1526 static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
QL 9:ca2e6010d9e2 1527 static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
QL 9:ca2e6010d9e2 1528 static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
QL 9:ca2e6010d9e2 1529 static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F),
QL 9:ca2e6010d9e2 1530 static_cast<uint8_t>(0xFE), static_cast<uint8_t>(0xFD),
QL 9:ca2e6010d9e2 1531 static_cast<uint8_t>(0xFB), static_cast<uint8_t>(0xF7),
QL 9:ca2e6010d9e2 1532 static_cast<uint8_t>(0xEF), static_cast<uint8_t>(0xDF),
QL 9:ca2e6010d9e2 1533 static_cast<uint8_t>(0xBF), static_cast<uint8_t>(0x7F)
QL 9:ca2e6010d9e2 1534 };
QL 9:ca2e6010d9e2 1535
QL 9:ca2e6010d9e2 1536 uint8_t const Q_ROM Q_ROM_VAR QF_div8Lkup[65] = {
QL 9:ca2e6010d9e2 1537 static_cast<uint8_t>(0), // unused location
QL 9:ca2e6010d9e2 1538 static_cast<uint8_t>(0), static_cast<uint8_t>(0), static_cast<uint8_t>(0),
QL 9:ca2e6010d9e2 1539 static_cast<uint8_t>(0), static_cast<uint8_t>(0), static_cast<uint8_t>(0),
QL 9:ca2e6010d9e2 1540 static_cast<uint8_t>(0), static_cast<uint8_t>(0),
QL 9:ca2e6010d9e2 1541 static_cast<uint8_t>(1), static_cast<uint8_t>(1), static_cast<uint8_t>(1),
QL 9:ca2e6010d9e2 1542 static_cast<uint8_t>(1), static_cast<uint8_t>(1), static_cast<uint8_t>(1),
QL 9:ca2e6010d9e2 1543 static_cast<uint8_t>(1), static_cast<uint8_t>(1),
QL 9:ca2e6010d9e2 1544 static_cast<uint8_t>(2), static_cast<uint8_t>(2), static_cast<uint8_t>(2),
QL 9:ca2e6010d9e2 1545 static_cast<uint8_t>(2), static_cast<uint8_t>(2), static_cast<uint8_t>(2),
QL 9:ca2e6010d9e2 1546 static_cast<uint8_t>(2), static_cast<uint8_t>(2),
QL 9:ca2e6010d9e2 1547 static_cast<uint8_t>(3), static_cast<uint8_t>(3), static_cast<uint8_t>(3),
QL 9:ca2e6010d9e2 1548 static_cast<uint8_t>(3), static_cast<uint8_t>(3), static_cast<uint8_t>(3),
QL 9:ca2e6010d9e2 1549 static_cast<uint8_t>(3), static_cast<uint8_t>(3),
QL 9:ca2e6010d9e2 1550 static_cast<uint8_t>(4), static_cast<uint8_t>(4), static_cast<uint8_t>(4),
QL 9:ca2e6010d9e2 1551 static_cast<uint8_t>(4), static_cast<uint8_t>(4), static_cast<uint8_t>(4),
QL 9:ca2e6010d9e2 1552 static_cast<uint8_t>(4), static_cast<uint8_t>(4),
QL 9:ca2e6010d9e2 1553 static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
QL 9:ca2e6010d9e2 1554 static_cast<uint8_t>(5), static_cast<uint8_t>(5), static_cast<uint8_t>(5),
QL 9:ca2e6010d9e2 1555 static_cast<uint8_t>(5), static_cast<uint8_t>(5),
QL 9:ca2e6010d9e2 1556 static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
QL 9:ca2e6010d9e2 1557 static_cast<uint8_t>(6), static_cast<uint8_t>(6), static_cast<uint8_t>(6),
QL 9:ca2e6010d9e2 1558 static_cast<uint8_t>(6), static_cast<uint8_t>(6),
QL 9:ca2e6010d9e2 1559 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1560 static_cast<uint8_t>(7), static_cast<uint8_t>(7), static_cast<uint8_t>(7),
QL 9:ca2e6010d9e2 1561 static_cast<uint8_t>(7), static_cast<uint8_t>(7)
QL 9:ca2e6010d9e2 1562 };
QL 9:ca2e6010d9e2 1563
QL 9:ca2e6010d9e2 1564 QP_END_
QL 9:ca2e6010d9e2 1565
QL 9:ca2e6010d9e2 1566 // "qf_tick.cpp" =============================================================
QL 9:ca2e6010d9e2 1567 /// \brief QF::tick() implementation.
QL 9:ca2e6010d9e2 1568
QL 9:ca2e6010d9e2 1569 QP_BEGIN_
QL 9:ca2e6010d9e2 1570
QL 9:ca2e6010d9e2 1571 //............................................................................
QL 9:ca2e6010d9e2 1572 #ifndef Q_SPY
QL 9:ca2e6010d9e2 1573 void QF::tick(void) { // see NOTE01
QL 9:ca2e6010d9e2 1574 #else
QL 9:ca2e6010d9e2 1575 void QF::tick(void const * const sender) {
QL 9:ca2e6010d9e2 1576 #endif
QL 9:ca2e6010d9e2 1577
QL 9:ca2e6010d9e2 1578 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 1579 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 1580
QL 9:ca2e6010d9e2 1581 QS_BEGIN_NOCRIT_(QS_QF_TICK, null_void, null_void)
QL 9:ca2e6010d9e2 1582 QS_TEC_(static_cast<QTimeEvtCtr>(++QS::tickCtr_)); // the tick counter
QL 9:ca2e6010d9e2 1583 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1584
QL 9:ca2e6010d9e2 1585 QTimeEvt *prev = null_tevt;
QL 9:ca2e6010d9e2 1586 for (QTimeEvt *t = QF_timeEvtListHead_; t != null_tevt; t = t->m_next) {
QL 9:ca2e6010d9e2 1587 if (t->m_ctr == tc_0) { // time evt. scheduled for removal?
QL 9:ca2e6010d9e2 1588 if (t == QF_timeEvtListHead_) {
QL 9:ca2e6010d9e2 1589 QF_timeEvtListHead_ = t->m_next;
QL 9:ca2e6010d9e2 1590 }
QL 9:ca2e6010d9e2 1591 else {
QL 9:ca2e6010d9e2 1592 Q_ASSERT(prev != null_tevt);
QL 9:ca2e6010d9e2 1593 prev->m_next = t->m_next;
QL 9:ca2e6010d9e2 1594 }
QL 9:ca2e6010d9e2 1595 QF_EVT_REF_CTR_DEC_(t); // mark as not linked
QL 9:ca2e6010d9e2 1596 }
QL 9:ca2e6010d9e2 1597 else {
QL 9:ca2e6010d9e2 1598 --t->m_ctr;
QL 9:ca2e6010d9e2 1599 if (t->m_ctr == tc_0) { // about to expire?
QL 9:ca2e6010d9e2 1600 if (t->m_interval != tc_0) { // periodic time event?
QL 9:ca2e6010d9e2 1601 t->m_ctr = t->m_interval; // rearm the time evt
QL 9:ca2e6010d9e2 1602 }
QL 9:ca2e6010d9e2 1603 else {
QL 9:ca2e6010d9e2 1604 QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_AUTO_DISARM, QS::teObj_, t)
QL 9:ca2e6010d9e2 1605 QS_OBJ_(t); // this time event object
QL 9:ca2e6010d9e2 1606 QS_OBJ_(t->m_act); // the active object
QL 9:ca2e6010d9e2 1607 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1608 }
QL 9:ca2e6010d9e2 1609
QL 9:ca2e6010d9e2 1610 QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_POST, QS::teObj_, t)
QL 9:ca2e6010d9e2 1611 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 1612 QS_OBJ_(t); // the time event object
QL 9:ca2e6010d9e2 1613 QS_SIG_(t->sig); // the signal of this time event
QL 9:ca2e6010d9e2 1614 QS_OBJ_(t->m_act); // the active object
QL 9:ca2e6010d9e2 1615 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1616
QL 9:ca2e6010d9e2 1617 QF_CRIT_EXIT_(); // leave crit. section before posting
QL 9:ca2e6010d9e2 1618 // POST() asserts internally if the queue overflows
QL 9:ca2e6010d9e2 1619 t->m_act->POST(t, sender);
QL 9:ca2e6010d9e2 1620 QF_CRIT_ENTRY_(); // re-enter crit. section to continue
QL 9:ca2e6010d9e2 1621
QL 9:ca2e6010d9e2 1622 if (t->m_ctr == tc_0) { // still marked to expire?
QL 9:ca2e6010d9e2 1623 if (t == QF_timeEvtListHead_) {
QL 9:ca2e6010d9e2 1624 QF_timeEvtListHead_ = t->m_next;
QL 9:ca2e6010d9e2 1625 }
QL 9:ca2e6010d9e2 1626 else {
QL 9:ca2e6010d9e2 1627 Q_ASSERT(prev != null_tevt);
QL 9:ca2e6010d9e2 1628 prev->m_next = t->m_next;
QL 9:ca2e6010d9e2 1629 }
QL 9:ca2e6010d9e2 1630 QF_EVT_REF_CTR_DEC_(t); // mark as removed
QL 9:ca2e6010d9e2 1631 }
QL 9:ca2e6010d9e2 1632 else {
QL 9:ca2e6010d9e2 1633 prev = t;
QL 9:ca2e6010d9e2 1634 }
QL 9:ca2e6010d9e2 1635 }
QL 9:ca2e6010d9e2 1636 else {
QL 9:ca2e6010d9e2 1637 prev = t;
QL 9:ca2e6010d9e2 1638 }
QL 9:ca2e6010d9e2 1639 }
QL 9:ca2e6010d9e2 1640 }
QL 9:ca2e6010d9e2 1641 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 1642 }
QL 9:ca2e6010d9e2 1643
QL 9:ca2e6010d9e2 1644 QP_END_
QL 9:ca2e6010d9e2 1645
QL 9:ca2e6010d9e2 1646 // "qmp_get.cpp" =============================================================
QL 9:ca2e6010d9e2 1647 /// \brief QMPool::get() and QF::getPoolMargin() implementation.
QL 9:ca2e6010d9e2 1648
QL 9:ca2e6010d9e2 1649 QP_BEGIN_
QL 9:ca2e6010d9e2 1650
QL 9:ca2e6010d9e2 1651 //............................................................................
QL 9:ca2e6010d9e2 1652 void *QMPool::get(void) {
QL 9:ca2e6010d9e2 1653 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 1654 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 1655
QL 9:ca2e6010d9e2 1656 QFreeBlock *fb = static_cast<QFreeBlock *>(m_free); // free block or NULL
QL 9:ca2e6010d9e2 1657 if (fb != static_cast<QFreeBlock *>(0)) { // free block available?
QL 9:ca2e6010d9e2 1658 m_free = fb->m_next; // adjust list head to the next free block
QL 9:ca2e6010d9e2 1659
QL 9:ca2e6010d9e2 1660 Q_ASSERT(m_nFree > static_cast<QMPoolCtr>(0)); // at least one free
QL 9:ca2e6010d9e2 1661 --m_nFree; // one free block less
QL 9:ca2e6010d9e2 1662 if (m_nMin > m_nFree) {
QL 9:ca2e6010d9e2 1663 m_nMin = m_nFree; // remember the minimum so far
QL 9:ca2e6010d9e2 1664 }
QL 9:ca2e6010d9e2 1665 }
QL 9:ca2e6010d9e2 1666
QL 9:ca2e6010d9e2 1667 QS_BEGIN_NOCRIT_(QS_QF_MPOOL_GET, QS::mpObj_, m_start)
QL 9:ca2e6010d9e2 1668 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 1669 QS_OBJ_(m_start); // the memory managed by this pool
QL 9:ca2e6010d9e2 1670 QS_MPC_(m_nFree); // the number of free blocks in the pool
QL 9:ca2e6010d9e2 1671 QS_MPC_(m_nMin); // the mninimum number of free blocks in the pool
QL 9:ca2e6010d9e2 1672 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1673
QL 9:ca2e6010d9e2 1674 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 1675 return fb; // return the block or NULL pointer to the caller
QL 9:ca2e6010d9e2 1676 }
QL 9:ca2e6010d9e2 1677 //............................................................................
QL 9:ca2e6010d9e2 1678 uint32_t QF::getPoolMargin(uint8_t const poolId) {
QL 9:ca2e6010d9e2 1679 Q_REQUIRE((u8_1 <= poolId) && (poolId <= QF_maxPool_));
QL 9:ca2e6010d9e2 1680
QL 9:ca2e6010d9e2 1681 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 1682 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 1683 uint32_t margin = static_cast<uint32_t>(QF_pool_[poolId - u8_1].m_nMin);
QL 9:ca2e6010d9e2 1684 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 1685
QL 9:ca2e6010d9e2 1686 return margin;
QL 9:ca2e6010d9e2 1687 }
QL 9:ca2e6010d9e2 1688
QL 9:ca2e6010d9e2 1689 QP_END_
QL 9:ca2e6010d9e2 1690
QL 9:ca2e6010d9e2 1691 // "qmp_init.cpp" ============================================================
QL 9:ca2e6010d9e2 1692 /// \brief QMPool::init() implementation.
QL 9:ca2e6010d9e2 1693
QL 9:ca2e6010d9e2 1694 QP_BEGIN_
QL 9:ca2e6010d9e2 1695
QL 9:ca2e6010d9e2 1696 //............................................................................
QL 9:ca2e6010d9e2 1697 void QMPool::init(void * const poolSto, uint32_t const poolSize,
QL 9:ca2e6010d9e2 1698 QMPoolSize const blockSize)
QL 9:ca2e6010d9e2 1699 {
QL 9:ca2e6010d9e2 1700 // The memory block must be valid
QL 9:ca2e6010d9e2 1701 // and the poolSize must fit at least one free block
QL 9:ca2e6010d9e2 1702 // and the blockSize must not be too close to the top of the dynamic range
QL 9:ca2e6010d9e2 1703 Q_REQUIRE((poolSto != null_void)
QL 9:ca2e6010d9e2 1704 && (poolSize >= static_cast<uint32_t>(sizeof(QFreeBlock)))
QL 9:ca2e6010d9e2 1705 && ((blockSize + static_cast<QMPoolSize>(sizeof(QFreeBlock)))
QL 9:ca2e6010d9e2 1706 > blockSize));
QL 9:ca2e6010d9e2 1707
QL 9:ca2e6010d9e2 1708 m_free = poolSto;
QL 9:ca2e6010d9e2 1709
QL 9:ca2e6010d9e2 1710 // round up the blockSize to fit an integer number of pointers
QL 9:ca2e6010d9e2 1711 m_blockSize = static_cast<QMPoolSize>(sizeof(QFreeBlock));//start with one
QL 9:ca2e6010d9e2 1712 uint32_t nblocks = static_cast<uint32_t>(1);//# free blocks in a mem block
QL 9:ca2e6010d9e2 1713 while (m_blockSize < blockSize) {
QL 9:ca2e6010d9e2 1714 m_blockSize += static_cast<QMPoolSize>(sizeof(QFreeBlock));
QL 9:ca2e6010d9e2 1715 ++nblocks;
QL 9:ca2e6010d9e2 1716 }
QL 9:ca2e6010d9e2 1717
QL 9:ca2e6010d9e2 1718 // the whole pool buffer must fit at least one rounded-up block
QL 9:ca2e6010d9e2 1719 Q_ASSERT(poolSize >= static_cast<uint32_t>(m_blockSize));
QL 9:ca2e6010d9e2 1720
QL 9:ca2e6010d9e2 1721 // chain all blocks together in a free-list...
QL 9:ca2e6010d9e2 1722 // don't chain last block
QL 9:ca2e6010d9e2 1723 uint32_t availSize = poolSize - static_cast<uint32_t>(m_blockSize);
QL 9:ca2e6010d9e2 1724 m_nTot = static_cast<QMPoolCtr>(1); // one (the last) block in the pool
QL 9:ca2e6010d9e2 1725 //start at the head of the free list
QL 9:ca2e6010d9e2 1726 QFreeBlock *fb = static_cast<QFreeBlock *>(m_free);
QL 9:ca2e6010d9e2 1727 while (availSize >= static_cast<uint32_t>(m_blockSize)) {
QL 9:ca2e6010d9e2 1728 fb->m_next = &QF_PTR_AT_(fb, nblocks); // setup the next link
QL 9:ca2e6010d9e2 1729 fb = fb->m_next; // advance to next block
QL 9:ca2e6010d9e2 1730 availSize -= static_cast<uint32_t>(m_blockSize);// less available size
QL 9:ca2e6010d9e2 1731 ++m_nTot; // increment the number of blocks so far
QL 9:ca2e6010d9e2 1732 }
QL 9:ca2e6010d9e2 1733
QL 9:ca2e6010d9e2 1734 fb->m_next = static_cast<QFreeBlock *>(0); // the last link points to NULL
QL 9:ca2e6010d9e2 1735 m_nFree = m_nTot; // all blocks are free
QL 9:ca2e6010d9e2 1736 m_nMin = m_nTot; // the minimum number of free blocks
QL 9:ca2e6010d9e2 1737 m_start = poolSto; // the original start this pool buffer
QL 9:ca2e6010d9e2 1738 m_end = fb; // the last block in this pool
QL 9:ca2e6010d9e2 1739
QL 9:ca2e6010d9e2 1740 QS_CRIT_STAT_
QL 9:ca2e6010d9e2 1741 QS_BEGIN_(QS_QF_MPOOL_INIT, QS::mpObj_, m_start)
QL 9:ca2e6010d9e2 1742 QS_OBJ_(m_start); // the memory managed by this pool
QL 9:ca2e6010d9e2 1743 QS_MPC_(m_nTot); // the total number of blocks
QL 9:ca2e6010d9e2 1744 QS_END_()
QL 9:ca2e6010d9e2 1745 }
QL 9:ca2e6010d9e2 1746
QL 9:ca2e6010d9e2 1747 QP_END_
QL 9:ca2e6010d9e2 1748
QL 9:ca2e6010d9e2 1749 // "qmp_put.cpp" =============================================================
QL 9:ca2e6010d9e2 1750 /// \brief QMPool::put() implementation.
QL 9:ca2e6010d9e2 1751
QL 9:ca2e6010d9e2 1752 QP_BEGIN_
QL 9:ca2e6010d9e2 1753
QL 9:ca2e6010d9e2 1754 // This macro is specifically and exclusively used for checking the range
QL 9:ca2e6010d9e2 1755 // of a block pointer returned to the pool. Such a check must rely on the
QL 9:ca2e6010d9e2 1756 // pointer arithmetic not compliant with the MISRA-C++:2008 rules ??? and
QL 9:ca2e6010d9e2 1757 // ???. Defining a specific macro for this purpose allows to selectively
QL 9:ca2e6010d9e2 1758 // disable the warnings for this particular case.
QL 9:ca2e6010d9e2 1759 //
QL 9:ca2e6010d9e2 1760 #define QF_PTR_RANGE_(x_, min_, max_) (((min_) <= (x_)) && ((x_) <= (max_)))
QL 9:ca2e6010d9e2 1761
QL 9:ca2e6010d9e2 1762 //............................................................................
QL 9:ca2e6010d9e2 1763 void QMPool::put(void * const b) {
QL 9:ca2e6010d9e2 1764
QL 9:ca2e6010d9e2 1765 Q_REQUIRE(m_nFree < m_nTot); // adding one free so, # free < total
QL 9:ca2e6010d9e2 1766 Q_REQUIRE(QF_PTR_RANGE_(b, m_start, m_end)); // b must be in range
QL 9:ca2e6010d9e2 1767
QL 9:ca2e6010d9e2 1768 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 1769 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 1770
QL 9:ca2e6010d9e2 1771 // link into the free list
QL 9:ca2e6010d9e2 1772 (static_cast<QFreeBlock*>(b))->m_next = static_cast<QFreeBlock *>(m_free);
QL 9:ca2e6010d9e2 1773 m_free = b; // set as new head of the free list
QL 9:ca2e6010d9e2 1774 ++m_nFree; // one more free block in this pool
QL 9:ca2e6010d9e2 1775
QL 9:ca2e6010d9e2 1776 QS_BEGIN_NOCRIT_(QS_QF_MPOOL_PUT, QS::mpObj_, m_start)
QL 9:ca2e6010d9e2 1777 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 1778 QS_OBJ_(m_start); // the memory managed by this pool
QL 9:ca2e6010d9e2 1779 QS_MPC_(m_nFree); // the number of free blocks in the pool
QL 9:ca2e6010d9e2 1780 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1781
QL 9:ca2e6010d9e2 1782 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 1783 }
QL 9:ca2e6010d9e2 1784
QL 9:ca2e6010d9e2 1785 QP_END_
QL 9:ca2e6010d9e2 1786
QL 9:ca2e6010d9e2 1787
QL 9:ca2e6010d9e2 1788 // "qte_arm.cpp" =============================================================
QL 9:ca2e6010d9e2 1789 /// \brief QF_timeEvtListHead_ definition and QTimeEvt::arm_() implementation.
QL 9:ca2e6010d9e2 1790
QL 9:ca2e6010d9e2 1791 QP_BEGIN_
QL 9:ca2e6010d9e2 1792
QL 9:ca2e6010d9e2 1793 // Package-scope objects -----------------------------------------------------
QL 9:ca2e6010d9e2 1794 QTimeEvt *QF_timeEvtListHead_; // head of linked list of time events
QL 9:ca2e6010d9e2 1795
QL 9:ca2e6010d9e2 1796 //............................................................................
QL 9:ca2e6010d9e2 1797 bool QF::noTimeEvtsActive(void) {
QL 9:ca2e6010d9e2 1798 return QF_timeEvtListHead_ == null_tevt;
QL 9:ca2e6010d9e2 1799 }
QL 9:ca2e6010d9e2 1800 //............................................................................
QL 9:ca2e6010d9e2 1801 void QTimeEvt::arm_(QActive * const act, QTimeEvtCtr const nTicks) {
QL 9:ca2e6010d9e2 1802 Q_REQUIRE((nTicks > tc_0) /* cannot arm with 0 ticks */
QL 9:ca2e6010d9e2 1803 && (act != null_act) /* Active object must be provided */
QL 9:ca2e6010d9e2 1804 && (m_ctr == tc_0) /* must be disarmed */
QL 9:ca2e6010d9e2 1805 && (static_cast<enum_t>(sig) >= Q_USER_SIG)); // valid signal
QL 9:ca2e6010d9e2 1806 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 1807 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 1808 m_ctr = nTicks;
QL 9:ca2e6010d9e2 1809 m_act = act;
QL 9:ca2e6010d9e2 1810 if (refCtr_ == u8_0) { // not linked?
QL 9:ca2e6010d9e2 1811 m_next = QF_timeEvtListHead_;
QL 9:ca2e6010d9e2 1812 QF_timeEvtListHead_ = this;
QL 9:ca2e6010d9e2 1813 QF_EVT_REF_CTR_INC_(this); // mark as linked
QL 9:ca2e6010d9e2 1814 }
QL 9:ca2e6010d9e2 1815
QL 9:ca2e6010d9e2 1816 QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_ARM, QS::teObj_, this)
QL 9:ca2e6010d9e2 1817 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 1818 QS_OBJ_(this); // this time event object
QL 9:ca2e6010d9e2 1819 QS_OBJ_(act); // the active object
QL 9:ca2e6010d9e2 1820 QS_TEC_(nTicks); // the number of ticks
QL 9:ca2e6010d9e2 1821 QS_TEC_(m_interval); // the interval
QL 9:ca2e6010d9e2 1822 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1823
QL 9:ca2e6010d9e2 1824 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 1825 }
QL 9:ca2e6010d9e2 1826
QL 9:ca2e6010d9e2 1827 QP_END_
QL 9:ca2e6010d9e2 1828
QL 9:ca2e6010d9e2 1829
QL 9:ca2e6010d9e2 1830 // "qte_ctor.cpp" ============================================================
QL 9:ca2e6010d9e2 1831 /// \brief QTimeEvt::QTimeEvt() implementation.
QL 9:ca2e6010d9e2 1832 QP_BEGIN_
QL 9:ca2e6010d9e2 1833
QL 9:ca2e6010d9e2 1834 //............................................................................
QL 9:ca2e6010d9e2 1835 QTimeEvt::QTimeEvt(enum_t const s)
QL 9:ca2e6010d9e2 1836 :
QL 9:ca2e6010d9e2 1837 #ifdef Q_EVT_CTOR
QL 9:ca2e6010d9e2 1838 QEvt(static_cast<QSignal>(s)),
QL 9:ca2e6010d9e2 1839 #endif
QL 9:ca2e6010d9e2 1840 m_next(null_tevt),
QL 9:ca2e6010d9e2 1841 m_act(null_act),
QL 9:ca2e6010d9e2 1842 m_ctr(tc_0),
QL 9:ca2e6010d9e2 1843 m_interval(tc_0)
QL 9:ca2e6010d9e2 1844 {
QL 9:ca2e6010d9e2 1845 Q_REQUIRE(s >= Q_USER_SIG); // signal must be valid
QL 9:ca2e6010d9e2 1846 #ifndef Q_EVT_CTOR
QL 9:ca2e6010d9e2 1847 sig = static_cast<QSignal>(s);
QL 9:ca2e6010d9e2 1848 #endif
QL 9:ca2e6010d9e2 1849 // time event must be static, see NOTE01
QL 9:ca2e6010d9e2 1850 poolId_ = u8_0; // not from any event pool
QL 9:ca2e6010d9e2 1851 refCtr_ = u8_0; // not linked
QL 9:ca2e6010d9e2 1852 }
QL 9:ca2e6010d9e2 1853
QL 9:ca2e6010d9e2 1854 QP_END_
QL 9:ca2e6010d9e2 1855
QL 9:ca2e6010d9e2 1856
QL 9:ca2e6010d9e2 1857 // "qte_ctr.cpp" =============================================================
QL 9:ca2e6010d9e2 1858 /// \brief QTimeEvt::ctr() implementation.
QL 9:ca2e6010d9e2 1859
QL 9:ca2e6010d9e2 1860 QP_BEGIN_
QL 9:ca2e6010d9e2 1861
QL 9:ca2e6010d9e2 1862 //............................................................................
QL 9:ca2e6010d9e2 1863 QTimeEvtCtr QTimeEvt::ctr(void) const {
QL 9:ca2e6010d9e2 1864 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 1865
QL 9:ca2e6010d9e2 1866 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 1867 QTimeEvtCtr ret = m_ctr;
QL 9:ca2e6010d9e2 1868
QL 9:ca2e6010d9e2 1869 QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_CTR, QS::teObj_, this)
QL 9:ca2e6010d9e2 1870 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 1871 QS_OBJ_(this); // this time event object
QL 9:ca2e6010d9e2 1872 QS_OBJ_(m_act); // the active object
QL 9:ca2e6010d9e2 1873 QS_TEC_(ret); // the current counter
QL 9:ca2e6010d9e2 1874 QS_TEC_(m_interval); // the interval
QL 9:ca2e6010d9e2 1875 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1876
QL 9:ca2e6010d9e2 1877 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 1878 return ret;
QL 9:ca2e6010d9e2 1879 }
QL 9:ca2e6010d9e2 1880
QL 9:ca2e6010d9e2 1881 QP_END_
QL 9:ca2e6010d9e2 1882
QL 9:ca2e6010d9e2 1883 // "qte_darm.cpp" ============================================================
QL 9:ca2e6010d9e2 1884 /// \brief QTimeEvt::disarm() implementation.
QL 9:ca2e6010d9e2 1885
QL 9:ca2e6010d9e2 1886 QP_BEGIN_
QL 9:ca2e6010d9e2 1887
QL 9:ca2e6010d9e2 1888 //............................................................................
QL 9:ca2e6010d9e2 1889 // NOTE: disarm a time evt (no harm in disarming an already disarmed time evt)
QL 9:ca2e6010d9e2 1890 bool QTimeEvt::disarm(void) {
QL 9:ca2e6010d9e2 1891 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 1892 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 1893 bool wasArmed;
QL 9:ca2e6010d9e2 1894 if (m_ctr != tc_0) { // is the time event actually armed?
QL 9:ca2e6010d9e2 1895 wasArmed = true;
QL 9:ca2e6010d9e2 1896
QL 9:ca2e6010d9e2 1897 QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_DISARM, QS::teObj_, this)
QL 9:ca2e6010d9e2 1898 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 1899 QS_OBJ_(this); // this time event object
QL 9:ca2e6010d9e2 1900 QS_OBJ_(m_act); // the active object
QL 9:ca2e6010d9e2 1901 QS_TEC_(m_ctr); // the number of ticks
QL 9:ca2e6010d9e2 1902 QS_TEC_(m_interval); // the interval
QL 9:ca2e6010d9e2 1903 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1904
QL 9:ca2e6010d9e2 1905 m_ctr = tc_0; // schedule removal from the list
QL 9:ca2e6010d9e2 1906 }
QL 9:ca2e6010d9e2 1907 else { // the time event was not armed
QL 9:ca2e6010d9e2 1908 wasArmed = false;
QL 9:ca2e6010d9e2 1909
QL 9:ca2e6010d9e2 1910 QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_DISARM_ATTEMPT, QS::teObj_, this)
QL 9:ca2e6010d9e2 1911 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 1912 QS_OBJ_(this); // this time event object
QL 9:ca2e6010d9e2 1913 QS_OBJ_(m_act); // the active object
QL 9:ca2e6010d9e2 1914 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1915 }
QL 9:ca2e6010d9e2 1916 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 1917 return wasArmed;
QL 9:ca2e6010d9e2 1918 }
QL 9:ca2e6010d9e2 1919
QL 9:ca2e6010d9e2 1920 QP_END_
QL 9:ca2e6010d9e2 1921
QL 9:ca2e6010d9e2 1922
QL 9:ca2e6010d9e2 1923 // "qte_rarm.cpp" ============================================================
QL 9:ca2e6010d9e2 1924 /// \brief QTimeEvt::rearm() implementation.
QL 9:ca2e6010d9e2 1925
QL 9:ca2e6010d9e2 1926 QP_BEGIN_
QL 9:ca2e6010d9e2 1927
QL 9:ca2e6010d9e2 1928 //............................................................................
QL 9:ca2e6010d9e2 1929 bool QTimeEvt::rearm(QTimeEvtCtr const nTicks) {
QL 9:ca2e6010d9e2 1930 Q_REQUIRE((nTicks > tc_0) /* cannot rearm with 0 ticks */
QL 9:ca2e6010d9e2 1931 && (m_act != null_act) /* active object must be valid */
QL 9:ca2e6010d9e2 1932 && (static_cast<enum_t>(sig) >= Q_USER_SIG)); // valid signal
QL 9:ca2e6010d9e2 1933
QL 9:ca2e6010d9e2 1934 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 1935 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 1936
QL 9:ca2e6010d9e2 1937 bool isArmed;
QL 9:ca2e6010d9e2 1938 if (m_ctr == tc_0) { // is this time event disarmed?
QL 9:ca2e6010d9e2 1939 isArmed = false;
QL 9:ca2e6010d9e2 1940 m_next = QF_timeEvtListHead_;
QL 9:ca2e6010d9e2 1941 if (QF_timeEvtListHead_ != null_tevt) {
QL 9:ca2e6010d9e2 1942 m_next = QF_timeEvtListHead_;
QL 9:ca2e6010d9e2 1943 QF_timeEvtListHead_ = this;
QL 9:ca2e6010d9e2 1944 QF_EVT_REF_CTR_INC_(this); // mark as linked
QL 9:ca2e6010d9e2 1945 }
QL 9:ca2e6010d9e2 1946 }
QL 9:ca2e6010d9e2 1947 else {
QL 9:ca2e6010d9e2 1948 isArmed = true;
QL 9:ca2e6010d9e2 1949 }
QL 9:ca2e6010d9e2 1950 m_ctr = nTicks; // re-load the tick counter (shift the phasing)
QL 9:ca2e6010d9e2 1951
QL 9:ca2e6010d9e2 1952 QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_REARM, QS::teObj_, this)
QL 9:ca2e6010d9e2 1953 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 1954 QS_OBJ_(this); // this time event object
QL 9:ca2e6010d9e2 1955 QS_OBJ_(m_act); // the active object
QL 9:ca2e6010d9e2 1956 QS_TEC_(m_ctr); // the number of ticks
QL 9:ca2e6010d9e2 1957 QS_TEC_(m_interval); // the interval
QL 9:ca2e6010d9e2 1958 QS_U8_(isArmed ? u8_1 : u8_0); // was the timer armed?
QL 9:ca2e6010d9e2 1959 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 1960
QL 9:ca2e6010d9e2 1961 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 1962 return isArmed;
QL 9:ca2e6010d9e2 1963 }
QL 9:ca2e6010d9e2 1964
QL 9:ca2e6010d9e2 1965 QP_END_
QL 9:ca2e6010d9e2 1966
QL 9:ca2e6010d9e2 1967
QL 9:ca2e6010d9e2 1968 //////////////////////////////////////////////////////////////////////////////
QL 9:ca2e6010d9e2 1969 // Kernel selection based on QK_PREEMPTIVE
QL 9:ca2e6010d9e2 1970 //
QL 9:ca2e6010d9e2 1971 #ifdef QK_PREEMPTIVE
QL 9:ca2e6010d9e2 1972
QL 9:ca2e6010d9e2 1973 // "qk_pkg.h" ================================================================
QL 9:ca2e6010d9e2 1974 /// \brief Internal (package scope) QK/C interface.
QL 9:ca2e6010d9e2 1975
QL 9:ca2e6010d9e2 1976 #ifndef QF_CRIT_STAT_TYPE
QL 9:ca2e6010d9e2 1977 /// \brief This is an internal macro for defining the critical section
QL 9:ca2e6010d9e2 1978 /// status type.
QL 9:ca2e6010d9e2 1979 ///
QL 9:ca2e6010d9e2 1980 /// The purpose of this macro is to enable writing the same code for the
QL 9:ca2e6010d9e2 1981 /// case when critical sectgion status type is defined and when it is not.
QL 9:ca2e6010d9e2 1982 /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
QL 9:ca2e6010d9e2 1983 /// provides the definition of the critical section status varaible.
QL 9:ca2e6010d9e2 1984 /// Otherwise this macro is empty.
QL 9:ca2e6010d9e2 1985 /// \sa #QF_CRIT_STAT_TYPE
QL 9:ca2e6010d9e2 1986 #define QF_CRIT_STAT_
QL 9:ca2e6010d9e2 1987
QL 9:ca2e6010d9e2 1988 /// \brief This is an internal macro for entering a critical section.
QL 9:ca2e6010d9e2 1989 ///
QL 9:ca2e6010d9e2 1990 /// The purpose of this macro is to enable writing the same code for the
QL 9:ca2e6010d9e2 1991 /// case when critical sectgion status type is defined and when it is not.
QL 9:ca2e6010d9e2 1992 /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
QL 9:ca2e6010d9e2 1993 /// invokes #QF_CRIT_ENTRY passing the key variable as the parameter.
QL 9:ca2e6010d9e2 1994 /// Otherwise #QF_CRIT_ENTRY is invoked with a dummy parameter.
QL 9:ca2e6010d9e2 1995 /// \sa #QF_CRIT_ENTRY
QL 9:ca2e6010d9e2 1996 #define QF_CRIT_ENTRY_() QF_CRIT_ENTRY(dummy)
QL 9:ca2e6010d9e2 1997
QL 9:ca2e6010d9e2 1998 /// \brief This is an internal macro for exiting a cricial section.
QL 9:ca2e6010d9e2 1999 ///
QL 9:ca2e6010d9e2 2000 /// The purpose of this macro is to enable writing the same code for the
QL 9:ca2e6010d9e2 2001 /// case when critical sectgion status type is defined and when it is not.
QL 9:ca2e6010d9e2 2002 /// If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
QL 9:ca2e6010d9e2 2003 /// invokes #QF_CRIT_EXIT passing the key variable as the parameter.
QL 9:ca2e6010d9e2 2004 /// Otherwise #QF_CRIT_EXIT is invoked with a dummy parameter.
QL 9:ca2e6010d9e2 2005 /// \sa #QF_CRIT_EXIT
QL 9:ca2e6010d9e2 2006 #define QF_CRIT_EXIT_() QF_CRIT_EXIT(dummy)
QL 9:ca2e6010d9e2 2007
QL 9:ca2e6010d9e2 2008 #else
QL 9:ca2e6010d9e2 2009 #define QF_CRIT_STAT_ QF_CRIT_STAT_TYPE critStat_;
QL 9:ca2e6010d9e2 2010 #define QF_CRIT_ENTRY_() QF_CRIT_ENTRY(critStat_)
QL 9:ca2e6010d9e2 2011 #define QF_CRIT_EXIT_() QF_CRIT_EXIT(critStat_)
QL 9:ca2e6010d9e2 2012 #endif
QL 9:ca2e6010d9e2 2013 // define for backwards compatibility, see NOTE01
QL 9:ca2e6010d9e2 2014 #ifndef QF_CRIT_STAT_TYPE
QL 9:ca2e6010d9e2 2015 #if !defined(QF_INT_DISABLE) && defined(QF_CRIT_ENTRY)
QL 9:ca2e6010d9e2 2016 #define QF_INT_DISABLE() QF_CRIT_ENTRY(dummy)
QL 9:ca2e6010d9e2 2017 #endif
QL 9:ca2e6010d9e2 2018 #if !defined(QF_INT_ENABLE) && defined(QF_CRIT_EXIT)
QL 9:ca2e6010d9e2 2019 #define QF_INT_ENABLE() QF_CRIT_EXIT(dummy)
QL 9:ca2e6010d9e2 2020 #endif
QL 9:ca2e6010d9e2 2021 #endif // QF_CRIT_STAT_TYPE
QL 9:ca2e6010d9e2 2022
QL 9:ca2e6010d9e2 2023 // package-scope objects...
QL 9:ca2e6010d9e2 2024 #ifndef QK_NO_MUTEX
QL 9:ca2e6010d9e2 2025 extern "C" uint8_t QK_ceilingPrio_; ///< QK mutex priority ceiling
QL 9:ca2e6010d9e2 2026 #endif
QL 9:ca2e6010d9e2 2027
QL 9:ca2e6010d9e2 2028 // "qk.cpp" ==================================================================
QL 9:ca2e6010d9e2 2029 /// \brief QK_readySet_, QK_currPrio_, and QK_intNest_ definitions and
QL 9:ca2e6010d9e2 2030 /// QK::getVersion(), QF::init(), QF::run(), QF::stop(),
QL 9:ca2e6010d9e2 2031 /// QActive::start(), QActive::stop() implementations.
QL 9:ca2e6010d9e2 2032
QL 9:ca2e6010d9e2 2033 // Public-scope objects ------------------------------------------------------
QL 9:ca2e6010d9e2 2034 extern "C" {
QL 9:ca2e6010d9e2 2035 #if (QF_MAX_ACTIVE <= 8)
QL 9:ca2e6010d9e2 2036 QP_ QPSet8 QK_readySet_; // ready set of QK
QL 9:ca2e6010d9e2 2037 #else
QL 9:ca2e6010d9e2 2038 QP_ QPSet64 QK_readySet_; // ready set of QK
QL 9:ca2e6010d9e2 2039 #endif
QL 9:ca2e6010d9e2 2040 // start with the QK scheduler locked
QL 9:ca2e6010d9e2 2041 uint8_t QK_currPrio_ = static_cast<uint8_t>(QF_MAX_ACTIVE + 1);
QL 9:ca2e6010d9e2 2042 uint8_t QK_intNest_; // start with nesting level of 0
QL 9:ca2e6010d9e2 2043
QL 9:ca2e6010d9e2 2044 } // extern "C"
QL 9:ca2e6010d9e2 2045
QL 9:ca2e6010d9e2 2046 QP_BEGIN_
QL 9:ca2e6010d9e2 2047
QL 9:ca2e6010d9e2 2048 //............................................................................
QL 9:ca2e6010d9e2 2049 char_t const Q_ROM * Q_ROM_VAR QK::getVersion(void) {
QL 9:ca2e6010d9e2 2050 uint8_t const u8_zero = static_cast<uint8_t>('0');
QL 9:ca2e6010d9e2 2051 static char_t const Q_ROM Q_ROM_VAR version[] = {
QL 9:ca2e6010d9e2 2052 static_cast<char_t>(((QP_VERSION >> 12) & 0xFU) + u8_zero),
QL 9:ca2e6010d9e2 2053 static_cast<char_t>('.'),
QL 9:ca2e6010d9e2 2054 static_cast<char_t>(((QP_VERSION >> 8) & 0xFU) + u8_zero),
QL 9:ca2e6010d9e2 2055 static_cast<char_t>('.'),
QL 9:ca2e6010d9e2 2056 static_cast<char_t>(((QP_VERSION >> 4) & 0xFU) + u8_zero),
QL 9:ca2e6010d9e2 2057 static_cast<char_t>((QP_VERSION & 0xFU) + u8_zero),
QL 9:ca2e6010d9e2 2058 static_cast<char_t>('\0')
QL 9:ca2e6010d9e2 2059 };
QL 9:ca2e6010d9e2 2060 return version;
QL 9:ca2e6010d9e2 2061 }
QL 9:ca2e6010d9e2 2062 //............................................................................
QL 9:ca2e6010d9e2 2063 void QF::init(void) {
QL 9:ca2e6010d9e2 2064 QK_init(); // QK initialization ("C" linkage, might be assembly)
QL 9:ca2e6010d9e2 2065 }
QL 9:ca2e6010d9e2 2066 //............................................................................
QL 9:ca2e6010d9e2 2067 void QF::stop(void) {
QL 9:ca2e6010d9e2 2068 QF::onCleanup(); // cleanup callback
QL 9:ca2e6010d9e2 2069 // nothing else to do for the QK preemptive kernel
QL 9:ca2e6010d9e2 2070 }
QL 9:ca2e6010d9e2 2071 //............................................................................
QL 9:ca2e6010d9e2 2072 static void initialize(void) {
QL 9:ca2e6010d9e2 2073 QK_currPrio_ = static_cast<uint8_t>(0); // priority for the QK idle loop
QL 9:ca2e6010d9e2 2074 uint8_t p = QK_schedPrio_();
QL 9:ca2e6010d9e2 2075 if (p != static_cast<uint8_t>(0)) {
QL 9:ca2e6010d9e2 2076 QK_sched_(p); // process all events produced so far
QL 9:ca2e6010d9e2 2077 }
QL 9:ca2e6010d9e2 2078 }
QL 9:ca2e6010d9e2 2079 //............................................................................
QL 9:ca2e6010d9e2 2080 int16_t QF::run(void) {
QL 9:ca2e6010d9e2 2081 QF_INT_DISABLE();
QL 9:ca2e6010d9e2 2082 initialize();
QL 9:ca2e6010d9e2 2083 onStartup(); // startup callback
QL 9:ca2e6010d9e2 2084 QF_INT_ENABLE();
QL 9:ca2e6010d9e2 2085
QL 9:ca2e6010d9e2 2086 for (;;) { // the QK idle loop
QL 9:ca2e6010d9e2 2087 QK::onIdle(); // invoke the QK on-idle callback
QL 9:ca2e6010d9e2 2088 }
QL 9:ca2e6010d9e2 2089 // this unreachable return is to make the compiler happy
QL 9:ca2e6010d9e2 2090 return static_cast<int16_t>(0);
QL 9:ca2e6010d9e2 2091 }
QL 9:ca2e6010d9e2 2092 //............................................................................
QL 9:ca2e6010d9e2 2093 void QActive::start(uint8_t const prio,
QL 9:ca2e6010d9e2 2094 QEvt const *qSto[], uint32_t const qLen,
QL 9:ca2e6010d9e2 2095 void * const stkSto, uint32_t const stkSize,
QL 9:ca2e6010d9e2 2096 QEvt const * const ie)
QL 9:ca2e6010d9e2 2097 {
QL 9:ca2e6010d9e2 2098 Q_REQUIRE((static_cast<uint8_t>(0) < prio)
QL 9:ca2e6010d9e2 2099 && (prio <= static_cast<uint8_t>(QF_MAX_ACTIVE)));
QL 9:ca2e6010d9e2 2100
QL 9:ca2e6010d9e2 2101 m_eQueue.init(qSto, static_cast<QEQueueCtr>(qLen)); // initialize queue
QL 9:ca2e6010d9e2 2102 m_prio = prio;
QL 9:ca2e6010d9e2 2103 QF::add_(this); // make QF aware of this active object
QL 9:ca2e6010d9e2 2104
QL 9:ca2e6010d9e2 2105 #if defined(QK_TLS) || defined(QK_EXT_SAVE)
QL 9:ca2e6010d9e2 2106 // in the QK port the parameter stkSize is used as the thread flags
QL 9:ca2e6010d9e2 2107 m_osObject = static_cast<uint8_t>(stkSize); // m_osObject contains flags
QL 9:ca2e6010d9e2 2108
QL 9:ca2e6010d9e2 2109 // in the QK port the parameter stkSto is used as the thread-local-storage
QL 9:ca2e6010d9e2 2110 m_thread = stkSto; // contains the pointer to the thread-local-storage
QL 9:ca2e6010d9e2 2111 #else
QL 9:ca2e6010d9e2 2112 Q_ASSERT((stkSto == static_cast<void *>(0))
QL 9:ca2e6010d9e2 2113 && (stkSize == static_cast<uint32_t>(0)));
QL 9:ca2e6010d9e2 2114 #endif
QL 9:ca2e6010d9e2 2115
QL 9:ca2e6010d9e2 2116 init(ie); // execute initial transition
QL 9:ca2e6010d9e2 2117
QL 9:ca2e6010d9e2 2118 QS_FLUSH(); // flush the trace buffer to the host
QL 9:ca2e6010d9e2 2119 }
QL 9:ca2e6010d9e2 2120 //............................................................................
QL 9:ca2e6010d9e2 2121 void QActive::stop(void) {
QL 9:ca2e6010d9e2 2122 QF::remove_(this); // remove this active object from the QF
QL 9:ca2e6010d9e2 2123 }
QL 9:ca2e6010d9e2 2124
QL 9:ca2e6010d9e2 2125 QP_END_
QL 9:ca2e6010d9e2 2126
QL 9:ca2e6010d9e2 2127 // "qk_sched" ================================================================
QL 9:ca2e6010d9e2 2128 /// \brief QK_schedPrio_() and QK_sched_() implementation.
QL 9:ca2e6010d9e2 2129
QL 9:ca2e6010d9e2 2130 //............................................................................
QL 9:ca2e6010d9e2 2131 // NOTE: the QK scheduler is entered and exited with interrupts DISABLED.
QL 9:ca2e6010d9e2 2132 // QK_sched_() is extern "C", so it does not belong to the QP namespace.
QL 9:ca2e6010d9e2 2133 //
QL 9:ca2e6010d9e2 2134 extern "C" {
QL 9:ca2e6010d9e2 2135
QL 9:ca2e6010d9e2 2136 //............................................................................
QL 9:ca2e6010d9e2 2137 // NOTE: QK schedPrio_() is entered and exited with interrupts DISABLED
QL 9:ca2e6010d9e2 2138 uint8_t QK_schedPrio_(void) {
QL 9:ca2e6010d9e2 2139
QL 9:ca2e6010d9e2 2140 uint8_t p = QK_readySet_.findMax();
QL 9:ca2e6010d9e2 2141
QL 9:ca2e6010d9e2 2142 #ifdef QK_NO_MUTEX
QL 9:ca2e6010d9e2 2143 if (p > QK_currPrio_) { // do we have a preemption?
QL 9:ca2e6010d9e2 2144 #else // QK priority-ceiling mutexes allowed
QL 9:ca2e6010d9e2 2145 if ((p > QK_currPrio_) && (p > QK_ceilingPrio_)) {
QL 9:ca2e6010d9e2 2146 #endif
QL 9:ca2e6010d9e2 2147 }
QL 9:ca2e6010d9e2 2148 else {
QL 9:ca2e6010d9e2 2149 p = static_cast<uint8_t>(0);
QL 9:ca2e6010d9e2 2150 }
QL 9:ca2e6010d9e2 2151 return p;
QL 9:ca2e6010d9e2 2152 }
QL 9:ca2e6010d9e2 2153 //............................................................................
QL 9:ca2e6010d9e2 2154 void QK_sched_(uint8_t p) {
QL 9:ca2e6010d9e2 2155
QL 9:ca2e6010d9e2 2156 uint8_t pin = QK_currPrio_; // save the initial priority
QL 9:ca2e6010d9e2 2157 QP_ QActive *a;
QL 9:ca2e6010d9e2 2158 #ifdef QK_TLS // thread-local storage used?
QL 9:ca2e6010d9e2 2159 uint8_t pprev = pin;
QL 9:ca2e6010d9e2 2160 #endif
QL 9:ca2e6010d9e2 2161 do {
QL 9:ca2e6010d9e2 2162 a = QP_ QF::active_[p]; // obtain the pointer to the AO
QL 9:ca2e6010d9e2 2163 QK_currPrio_ = p; // this becomes the current task priority
QL 9:ca2e6010d9e2 2164
QL 9:ca2e6010d9e2 2165 #ifdef QK_TLS // thread-local storage used?
QL 9:ca2e6010d9e2 2166 if (p != pprev) { // are we changing threads?
QL 9:ca2e6010d9e2 2167 QK_TLS(a); // switch new thread-local storage
QL 9:ca2e6010d9e2 2168 pprev = p;
QL 9:ca2e6010d9e2 2169 }
QL 9:ca2e6010d9e2 2170 #endif
QL 9:ca2e6010d9e2 2171 QS_BEGIN_NOCRIT_(QP_ QS_QK_SCHEDULE, QP_ QS::aoObj_, a)
QL 9:ca2e6010d9e2 2172 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 2173 QS_U8_(p); // the priority of the active object
QL 9:ca2e6010d9e2 2174 QS_U8_(pin); // the preempted priority
QL 9:ca2e6010d9e2 2175 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 2176
QL 9:ca2e6010d9e2 2177 QF_INT_ENABLE(); // unconditionally enable interrupts
QL 9:ca2e6010d9e2 2178
QL 9:ca2e6010d9e2 2179 QP_ QEvt const *e = a->get_(); // get the next event for this AO
QL 9:ca2e6010d9e2 2180 a->dispatch(e); // dispatch e to this AO
QL 9:ca2e6010d9e2 2181 QP_ QF::gc(e); // garbage collect the event, if necessary
QL 9:ca2e6010d9e2 2182
QL 9:ca2e6010d9e2 2183 // determine the next highest-priority AO ready to run
QL 9:ca2e6010d9e2 2184 QF_INT_DISABLE(); // disable interrupts
QL 9:ca2e6010d9e2 2185 p = QK_readySet_.findMax();
QL 9:ca2e6010d9e2 2186
QL 9:ca2e6010d9e2 2187 #ifdef QK_NO_MUTEX
QL 9:ca2e6010d9e2 2188 } while (p > pin); // is the new priority higher than initial?
QL 9:ca2e6010d9e2 2189 #else // QK priority-ceiling mutexes allowed
QL 9:ca2e6010d9e2 2190 } while ((p > pin) && (p > QK_ceilingPrio_));
QL 9:ca2e6010d9e2 2191 #endif
QL 9:ca2e6010d9e2 2192
QL 9:ca2e6010d9e2 2193 QK_currPrio_ = pin; // restore the initial priority
QL 9:ca2e6010d9e2 2194
QL 9:ca2e6010d9e2 2195 #ifdef QK_TLS // thread-local storage used?
QL 9:ca2e6010d9e2 2196 if (pin != static_cast<uint8_t>(0)) { // no extended context for idle loop
QL 9:ca2e6010d9e2 2197 a = QP_ QF::active_[pin]; // the pointer to the preempted AO
QL 9:ca2e6010d9e2 2198 QK_TLS(a); // restore the original TLS
QL 9:ca2e6010d9e2 2199 }
QL 9:ca2e6010d9e2 2200 #endif
QL 9:ca2e6010d9e2 2201 }
QL 9:ca2e6010d9e2 2202
QL 9:ca2e6010d9e2 2203 } // extern "C"
QL 9:ca2e6010d9e2 2204
QL 9:ca2e6010d9e2 2205 #ifndef QK_NO_MUTEX
QL 9:ca2e6010d9e2 2206
QL 9:ca2e6010d9e2 2207 // "qk_mutex.cpp" ============================================================
QL 9:ca2e6010d9e2 2208 /// \brief QK::mutexLock()/QK::mutexUnlock() implementation.
QL 9:ca2e6010d9e2 2209
QL 9:ca2e6010d9e2 2210 // package-scope objects -----------------------------------------------------
QL 9:ca2e6010d9e2 2211 extern "C" {
QL 9:ca2e6010d9e2 2212 uint8_t QK_ceilingPrio_; // ceiling priority of a mutex
QL 9:ca2e6010d9e2 2213 }
QL 9:ca2e6010d9e2 2214
QL 9:ca2e6010d9e2 2215 QP_BEGIN_
QL 9:ca2e6010d9e2 2216
QL 9:ca2e6010d9e2 2217 //............................................................................
QL 9:ca2e6010d9e2 2218 QMutex QK::mutexLock(uint8_t const prioCeiling) {
QL 9:ca2e6010d9e2 2219 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 2220 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 2221 uint8_t mutex = QK_ceilingPrio_; // original QK priority ceiling to return
QL 9:ca2e6010d9e2 2222 if (QK_ceilingPrio_ < prioCeiling) {
QL 9:ca2e6010d9e2 2223 QK_ceilingPrio_ = prioCeiling; // raise the QK priority ceiling
QL 9:ca2e6010d9e2 2224 }
QL 9:ca2e6010d9e2 2225
QL 9:ca2e6010d9e2 2226 QS_BEGIN_NOCRIT_(QS_QK_MUTEX_LOCK,
QL 9:ca2e6010d9e2 2227 static_cast<void *>(0), static_cast<void *>(0))
QL 9:ca2e6010d9e2 2228 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 2229 QS_U8_(mutex); // the original priority
QL 9:ca2e6010d9e2 2230 QS_U8_(QK_ceilingPrio_); // the current priority ceiling
QL 9:ca2e6010d9e2 2231 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 2232
QL 9:ca2e6010d9e2 2233 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 2234 return mutex;
QL 9:ca2e6010d9e2 2235 }
QL 9:ca2e6010d9e2 2236 //............................................................................
QL 9:ca2e6010d9e2 2237 void QK::mutexUnlock(QMutex mutex) {
QL 9:ca2e6010d9e2 2238 QF_CRIT_STAT_
QL 9:ca2e6010d9e2 2239 QF_CRIT_ENTRY_();
QL 9:ca2e6010d9e2 2240
QL 9:ca2e6010d9e2 2241 QS_BEGIN_NOCRIT_(QS_QK_MUTEX_UNLOCK,
QL 9:ca2e6010d9e2 2242 static_cast<void *>(0), static_cast<void *>(0))
QL 9:ca2e6010d9e2 2243 QS_TIME_(); // timestamp
QL 9:ca2e6010d9e2 2244 QS_U8_(mutex); // the original priority
QL 9:ca2e6010d9e2 2245 QS_U8_(QK_ceilingPrio_); // the current priority ceiling
QL 9:ca2e6010d9e2 2246 QS_END_NOCRIT_()
QL 9:ca2e6010d9e2 2247
QL 9:ca2e6010d9e2 2248 if (QK_ceilingPrio_ > mutex) {
QL 9:ca2e6010d9e2 2249 QK_ceilingPrio_ = mutex; // restore the saved priority ceiling
QL 9:ca2e6010d9e2 2250 mutex = QK_schedPrio_(); // reuse 'mutex' to hold priority
QL 9:ca2e6010d9e2 2251 if (mutex != static_cast<uint8_t>(0)) {
QL 9:ca2e6010d9e2 2252 QK_sched_(mutex);
QL 9:ca2e6010d9e2 2253 }
QL 9:ca2e6010d9e2 2254 }
QL 9:ca2e6010d9e2 2255 QF_CRIT_EXIT_();
QL 9:ca2e6010d9e2 2256 }
QL 9:ca2e6010d9e2 2257
QL 9:ca2e6010d9e2 2258 QP_END_
QL 9:ca2e6010d9e2 2259
QL 9:ca2e6010d9e2 2260 #endif // QK_NO_MUTEX
QL 9:ca2e6010d9e2 2261
QL 9:ca2e6010d9e2 2262 #else // QK_PREEMPTIVE
QL 9:ca2e6010d9e2 2263
QL 9:ca2e6010d9e2 2264 // "qvanilla.cpp" ============================================================
QL 9:ca2e6010d9e2 2265 /// \brief "vanilla" cooperative kernel,
QL 9:ca2e6010d9e2 2266 /// QActive::start(), QActive::stop(), and QF::run() implementation.
QL 9:ca2e6010d9e2 2267
QL 9:ca2e6010d9e2 2268 QP_BEGIN_
QL 9:ca2e6010d9e2 2269
QL 9:ca2e6010d9e2 2270 // Package-scope objects -----------------------------------------------------
QL 9:ca2e6010d9e2 2271 extern "C" {
QL 9:ca2e6010d9e2 2272 #if (QF_MAX_ACTIVE <= 8)
QL 9:ca2e6010d9e2 2273 QPSet8 QF_readySet_; // ready set of active objects
QL 9:ca2e6010d9e2 2274 #else
QL 9:ca2e6010d9e2 2275 QPSet64 QF_readySet_; // ready set of active objects
QL 9:ca2e6010d9e2 2276 #endif
QL 9:ca2e6010d9e2 2277
QL 9:ca2e6010d9e2 2278 uint8_t QF_currPrio_; ///< current task/interrupt priority
QL 9:ca2e6010d9e2 2279 uint8_t QF_intNest_; ///< interrupt nesting level
QL 9:ca2e6010d9e2 2280
QL 9:ca2e6010d9e2 2281 } // extern "C"
QL 9:ca2e6010d9e2 2282
QL 9:ca2e6010d9e2 2283 //............................................................................
QL 9:ca2e6010d9e2 2284 void QF::init(void) {
QL 9:ca2e6010d9e2 2285 // nothing to do for the "vanilla" kernel
QL 9:ca2e6010d9e2 2286 }
QL 9:ca2e6010d9e2 2287 //............................................................................
QL 9:ca2e6010d9e2 2288 void QF::stop(void) {
QL 9:ca2e6010d9e2 2289 onCleanup(); // cleanup callback
QL 9:ca2e6010d9e2 2290 // nothing else to do for the "vanilla" kernel
QL 9:ca2e6010d9e2 2291 }
QL 9:ca2e6010d9e2 2292 //............................................................................
QL 9:ca2e6010d9e2 2293 int16_t QF::run(void) {
QL 9:ca2e6010d9e2 2294 onStartup(); // startup callback
QL 9:ca2e6010d9e2 2295
QL 9:ca2e6010d9e2 2296 for (;;) { // the bacground loop
QL 9:ca2e6010d9e2 2297 QF_INT_DISABLE();
QL 9:ca2e6010d9e2 2298 if (QF_readySet_.notEmpty()) {
QL 9:ca2e6010d9e2 2299 uint8_t p = QF_readySet_.findMax();
QL 9:ca2e6010d9e2 2300 QActive *a = active_[p];
QL 9:ca2e6010d9e2 2301 QF_currPrio_ = p; // save the current priority
QL 9:ca2e6010d9e2 2302 QF_INT_ENABLE();
QL 9:ca2e6010d9e2 2303
QL 9:ca2e6010d9e2 2304 QEvt const *e = a->get_(); // get the next event for this AO
QL 9:ca2e6010d9e2 2305 a->dispatch(e); // dispatch evt to the HSM
QL 9:ca2e6010d9e2 2306 gc(e); // determine if event is garbage and collect it if so
QL 9:ca2e6010d9e2 2307 }
QL 9:ca2e6010d9e2 2308 else {
QL 9:ca2e6010d9e2 2309 onIdle(); // see NOTE01
QL 9:ca2e6010d9e2 2310 }
QL 9:ca2e6010d9e2 2311 }
QL 9:ca2e6010d9e2 2312 // this unreachable return is to make the compiler happy
QL 9:ca2e6010d9e2 2313 return static_cast<int16_t>(0);
QL 9:ca2e6010d9e2 2314 }
QL 9:ca2e6010d9e2 2315 //............................................................................
QL 9:ca2e6010d9e2 2316 void QActive::start(uint8_t const prio,
QL 9:ca2e6010d9e2 2317 QEvt const *qSto[], uint32_t const qLen,
QL 9:ca2e6010d9e2 2318 void * const stkSto, uint32_t const,
QL 9:ca2e6010d9e2 2319 QEvt const * const ie)
QL 9:ca2e6010d9e2 2320 {
QL 9:ca2e6010d9e2 2321 Q_REQUIRE((u8_0 < prio) && (prio <= static_cast<uint8_t>(QF_MAX_ACTIVE))
QL 9:ca2e6010d9e2 2322 && (stkSto == null_void)); // does not need per-actor stack
QL 9:ca2e6010d9e2 2323
QL 9:ca2e6010d9e2 2324 m_eQueue.init(qSto, static_cast<QEQueueCtr>(qLen)); // initialize QEQueue
QL 9:ca2e6010d9e2 2325 m_prio = prio; // set the QF priority of this active object
QL 9:ca2e6010d9e2 2326 QF::add_(this); // make QF aware of this active object
QL 9:ca2e6010d9e2 2327 init(ie); // execute initial transition
QL 9:ca2e6010d9e2 2328
QL 9:ca2e6010d9e2 2329 QS_FLUSH(); // flush the trace buffer to the host
QL 9:ca2e6010d9e2 2330 }
QL 9:ca2e6010d9e2 2331 //............................................................................
QL 9:ca2e6010d9e2 2332 void QActive::stop(void) {
QL 9:ca2e6010d9e2 2333 QF::remove_(this);
QL 9:ca2e6010d9e2 2334 }
QL 9:ca2e6010d9e2 2335
QL 9:ca2e6010d9e2 2336 QP_END_
QL 9:ca2e6010d9e2 2337
QL 9:ca2e6010d9e2 2338 //////////////////////////////////////////////////////////////////////////////
QL 9:ca2e6010d9e2 2339 // NOTE01:
QL 9:ca2e6010d9e2 2340 // QF::onIdle() must be called with interrupts DISABLED because the
QL 9:ca2e6010d9e2 2341 // determination of the idle condition (no events in the queues) can change
QL 9:ca2e6010d9e2 2342 // at any time by an interrupt posting events to a queue. The QF::onIdle()
QL 9:ca2e6010d9e2 2343 // MUST enable interrups internally, perhaps at the same time as putting the
QL 9:ca2e6010d9e2 2344 // CPU into a power-saving mode.
QL 9:ca2e6010d9e2 2345 //
QL 9:ca2e6010d9e2 2346
QL 9:ca2e6010d9e2 2347 extern "C" {
QL 9:ca2e6010d9e2 2348
QL 9:ca2e6010d9e2 2349 void QK_sched_(uint8_t p) { // dummy empty definition for qk_port.s
QL 9:ca2e6010d9e2 2350 (void)p;
QL 9:ca2e6010d9e2 2351 }
QL 9:ca2e6010d9e2 2352
QL 9:ca2e6010d9e2 2353 uint8_t QK_schedPrio_(void) { // dummy empty definition for qk_port.s
QL 9:ca2e6010d9e2 2354 return static_cast<uint8_t>(0U);
QL 9:ca2e6010d9e2 2355 }
QL 9:ca2e6010d9e2 2356
QL 9:ca2e6010d9e2 2357 } // extern "C"
QL 9:ca2e6010d9e2 2358
QL 9:ca2e6010d9e2 2359 #endif // QK_PREEMPTIVE
QL 9:ca2e6010d9e2 2360
QL 9:ca2e6010d9e2 2361 //////////////////////////////////////////////////////////////////////////////
QL 9:ca2e6010d9e2 2362 #ifdef Q_SPY
QL 9:ca2e6010d9e2 2363
QL 9:ca2e6010d9e2 2364 // "qs_pkg.h" ================================================================
QL 9:ca2e6010d9e2 2365 /// \brief Internal (package scope) QS/C++ interface.
QL 9:ca2e6010d9e2 2366
QL 9:ca2e6010d9e2 2367 QP_BEGIN_
QL 9:ca2e6010d9e2 2368
QL 9:ca2e6010d9e2 2369 /// \brief QS ring buffer counter and offset type
QL 9:ca2e6010d9e2 2370 typedef uint16_t QSCtr;
QL 9:ca2e6010d9e2 2371
QL 9:ca2e6010d9e2 2372 /// \brief Internal QS macro to insert an un-escaped byte into
QL 9:ca2e6010d9e2 2373 /// the QS buffer
QL 9:ca2e6010d9e2 2374 ////
QL 9:ca2e6010d9e2 2375 #define QS_INSERT_BYTE(b_) \
QL 9:ca2e6010d9e2 2376 QS_PTR_AT_(QS_head_) = (b_); \
QL 9:ca2e6010d9e2 2377 ++QS_head_; \
QL 9:ca2e6010d9e2 2378 if (QS_head_ == QS_end_) { \
QL 9:ca2e6010d9e2 2379 QS_head_ = static_cast<QSCtr>(0); \
QL 9:ca2e6010d9e2 2380 } \
QL 9:ca2e6010d9e2 2381 ++QS_used_;
QL 9:ca2e6010d9e2 2382
QL 9:ca2e6010d9e2 2383 /// \brief Internal QS macro to insert an escaped byte into the QS buffer
QL 9:ca2e6010d9e2 2384 #define QS_INSERT_ESC_BYTE(b_) \
QL 9:ca2e6010d9e2 2385 QS_chksum_ = static_cast<uint8_t>(QS_chksum_ + (b_)); \
QL 9:ca2e6010d9e2 2386 if (((b_) == QS_FRAME) || ((b_) == QS_ESC)) { \
QL 9:ca2e6010d9e2 2387 QS_INSERT_BYTE(QS_ESC) \
QL 9:ca2e6010d9e2 2388 QS_INSERT_BYTE(static_cast<uint8_t>((b_) ^ QS_ESC_XOR)) \
QL 9:ca2e6010d9e2 2389 } \
QL 9:ca2e6010d9e2 2390 else { \
QL 9:ca2e6010d9e2 2391 QS_INSERT_BYTE(b_) \
QL 9:ca2e6010d9e2 2392 }
QL 9:ca2e6010d9e2 2393
QL 9:ca2e6010d9e2 2394 /// \brief Internal QS macro to insert a escaped checksum byte into
QL 9:ca2e6010d9e2 2395 /// the QS buffer
QL 9:ca2e6010d9e2 2396 #define QS_INSERT_CHKSUM_BYTE() \
QL 9:ca2e6010d9e2 2397 QS_chksum_ = static_cast<uint8_t>(~QS_chksum_); \
QL 9:ca2e6010d9e2 2398 if ((QS_chksum_ == QS_FRAME) || (QS_chksum_ == QS_ESC)) { \
QL 9:ca2e6010d9e2 2399 QS_INSERT_BYTE(QS_ESC) \
QL 9:ca2e6010d9e2 2400 QS_INSERT_BYTE(static_cast<uint8_t>(QS_chksum_ ^ QS_ESC_XOR)) \
QL 9:ca2e6010d9e2 2401 } \
QL 9:ca2e6010d9e2 2402 else { \
QL 9:ca2e6010d9e2 2403 QS_INSERT_BYTE(QS_chksum_) \
QL 9:ca2e6010d9e2 2404 }
QL 9:ca2e6010d9e2 2405
QL 9:ca2e6010d9e2 2406
QL 9:ca2e6010d9e2 2407 /// \brief Internal QS macro to access the QS ring buffer
QL 9:ca2e6010d9e2 2408 ///
QL 9:ca2e6010d9e2 2409 /// \note The QS buffer is allocated by the user and is accessed through the
QL 9:ca2e6010d9e2 2410 /// pointer QS_ring_, which violates the MISRA-C 2004 Rule 17.4(req), pointer
QL 9:ca2e6010d9e2 2411 /// arithmetic other than array indexing. Encapsulating this violation in a
QL 9:ca2e6010d9e2 2412 /// macro allows to selectively suppress this specific deviation.
QL 9:ca2e6010d9e2 2413 #define QS_PTR_AT_(i_) (QS_ring_[i_])
QL 9:ca2e6010d9e2 2414
QL 9:ca2e6010d9e2 2415
QL 9:ca2e6010d9e2 2416 /// \brief Frame character of the QS output protocol
QL 9:ca2e6010d9e2 2417 uint8_t const QS_FRAME = static_cast<uint8_t>(0x7E);
QL 9:ca2e6010d9e2 2418
QL 9:ca2e6010d9e2 2419 /// \brief Escape character of the QS output protocol
QL 9:ca2e6010d9e2 2420 uint8_t const QS_ESC = static_cast<uint8_t>(0x7D);
QL 9:ca2e6010d9e2 2421
QL 9:ca2e6010d9e2 2422 /// \brief Escape modifier of the QS output protocol
QL 9:ca2e6010d9e2 2423 ///
QL 9:ca2e6010d9e2 2424 /// The escaped byte is XOR-ed with the escape modifier before it is inserted
QL 9:ca2e6010d9e2 2425 /// into the QS buffer.
QL 9:ca2e6010d9e2 2426 uint8_t const QS_ESC_XOR = static_cast<uint8_t>(0x20);
QL 9:ca2e6010d9e2 2427
QL 9:ca2e6010d9e2 2428 #ifndef Q_ROM_BYTE
QL 9:ca2e6010d9e2 2429 /// \brief Macro to access a byte allocated in ROM
QL 9:ca2e6010d9e2 2430 ///
QL 9:ca2e6010d9e2 2431 /// Some compilers for Harvard-architecture MCUs, such as gcc for AVR, do
QL 9:ca2e6010d9e2 2432 /// not generate correct code for accessing data allocated in the program
QL 9:ca2e6010d9e2 2433 /// space (ROM). The workaround for such compilers is to explictly add
QL 9:ca2e6010d9e2 2434 /// assembly code to access each data element allocated in the program
QL 9:ca2e6010d9e2 2435 /// space. The macro Q_ROM_BYTE() retrieves a byte from the given ROM
QL 9:ca2e6010d9e2 2436 /// address.
QL 9:ca2e6010d9e2 2437 ///
QL 9:ca2e6010d9e2 2438 /// The Q_ROM_BYTE() macro should be defined for the compilers that
QL 9:ca2e6010d9e2 2439 /// cannot handle correctly data allocated in ROM (such as the gcc).
QL 9:ca2e6010d9e2 2440 /// If the macro is left undefined, the default definition simply returns
QL 9:ca2e6010d9e2 2441 /// the argument and lets the compiler generate the correct code.
QL 9:ca2e6010d9e2 2442 #define Q_ROM_BYTE(rom_var_) (rom_var_)
QL 9:ca2e6010d9e2 2443 #endif
QL 9:ca2e6010d9e2 2444
QL 9:ca2e6010d9e2 2445 //............................................................................
QL 9:ca2e6010d9e2 2446 extern uint8_t *QS_ring_; ///< pointer to the start of the ring buffer
QL 9:ca2e6010d9e2 2447 extern QSCtr QS_end_; ///< offset of the end of the ring buffer
QL 9:ca2e6010d9e2 2448 extern QSCtr QS_head_; ///< offset to where next byte will be inserted
QL 9:ca2e6010d9e2 2449 extern QSCtr QS_tail_; ///< offset of where next event will be extracted
QL 9:ca2e6010d9e2 2450 extern QSCtr QS_used_; ///< number of bytes currently in the ring buffer
QL 9:ca2e6010d9e2 2451 extern uint8_t QS_seq_; ///< the record sequence number
QL 9:ca2e6010d9e2 2452 extern uint8_t QS_chksum_; ///< the checksum of the current record
QL 9:ca2e6010d9e2 2453 extern uint8_t QS_full_; ///< the ring buffer is temporarily full
QL 9:ca2e6010d9e2 2454
QL 9:ca2e6010d9e2 2455 QP_END_
QL 9:ca2e6010d9e2 2456
QL 9:ca2e6010d9e2 2457
QL 9:ca2e6010d9e2 2458 // "qs.cpp" ==================================================================
QL 9:ca2e6010d9e2 2459 /// \brief QS internal variables definitions and core QS functions
QL 9:ca2e6010d9e2 2460 /// implementations.
QL 9:ca2e6010d9e2 2461
QL 9:ca2e6010d9e2 2462 QP_BEGIN_
QL 9:ca2e6010d9e2 2463
QL 9:ca2e6010d9e2 2464 //............................................................................
QL 9:ca2e6010d9e2 2465 uint8_t QS::glbFilter_[32]; // global QS filter
QL 9:ca2e6010d9e2 2466
QL 9:ca2e6010d9e2 2467 //............................................................................
QL 9:ca2e6010d9e2 2468 uint8_t *QS_ring_; // pointer to the start of the ring buffer
QL 9:ca2e6010d9e2 2469 QSCtr QS_end_; // offset of the end of the ring buffer
QL 9:ca2e6010d9e2 2470 QSCtr QS_head_; // offset to where next byte will be inserted
QL 9:ca2e6010d9e2 2471 QSCtr QS_tail_; // offset of where next byte will be extracted
QL 9:ca2e6010d9e2 2472 QSCtr QS_used_; // number of bytes currently in the ring buffer
QL 9:ca2e6010d9e2 2473 uint8_t QS_seq_; // the record sequence number
QL 9:ca2e6010d9e2 2474 uint8_t QS_chksum_; // the checksum of the current record
QL 9:ca2e6010d9e2 2475 uint8_t QS_full_; // the ring buffer is temporarily full
QL 9:ca2e6010d9e2 2476
QL 9:ca2e6010d9e2 2477 //............................................................................
QL 9:ca2e6010d9e2 2478 char_t const Q_ROM * Q_ROM_VAR QS::getVersion(void) {
QL 9:ca2e6010d9e2 2479 uint8_t const u8_zero = static_cast<uint8_t>('0');
QL 9:ca2e6010d9e2 2480 static char_t const Q_ROM Q_ROM_VAR version[] = {
QL 9:ca2e6010d9e2 2481 static_cast<char_t>(((QP_VERSION >> 12) & 0xFU) + u8_zero),
QL 9:ca2e6010d9e2 2482 static_cast<char_t>('.'),
QL 9:ca2e6010d9e2 2483 static_cast<char_t>(((QP_VERSION >> 8) & 0xFU) + u8_zero),
QL 9:ca2e6010d9e2 2484 static_cast<char_t>('.'),
QL 9:ca2e6010d9e2 2485 static_cast<char_t>(((QP_VERSION >> 4) & 0xFU) + u8_zero),
QL 9:ca2e6010d9e2 2486 static_cast<char_t>((QP_VERSION & 0xFU) + u8_zero),
QL 9:ca2e6010d9e2 2487 static_cast<char_t>('\0')
QL 9:ca2e6010d9e2 2488 };
QL 9:ca2e6010d9e2 2489 return version;
QL 9:ca2e6010d9e2 2490 }
QL 9:ca2e6010d9e2 2491 //............................................................................
QL 9:ca2e6010d9e2 2492 void QS::initBuf(uint8_t sto[], uint32_t const stoSize) {
QL 9:ca2e6010d9e2 2493 QS_ring_ = &sto[0];
QL 9:ca2e6010d9e2 2494 QS_end_ = static_cast<QSCtr>(stoSize);
QL 9:ca2e6010d9e2 2495 }
QL 9:ca2e6010d9e2 2496 //............................................................................
QL 9:ca2e6010d9e2 2497 void QS::filterOn(uint8_t const rec) {
QL 9:ca2e6010d9e2 2498 if (rec == QS_ALL_RECORDS) {
QL 9:ca2e6010d9e2 2499 uint8_t i;
QL 9:ca2e6010d9e2 2500 for (i = static_cast<uint8_t>(0);
QL 9:ca2e6010d9e2 2501 i < static_cast<uint8_t>(sizeof(glbFilter_));
QL 9:ca2e6010d9e2 2502 ++i)
QL 9:ca2e6010d9e2 2503 {
QL 9:ca2e6010d9e2 2504 glbFilter_[i] = static_cast<uint8_t>(0xFF);
QL 9:ca2e6010d9e2 2505 }
QL 9:ca2e6010d9e2 2506 }
QL 9:ca2e6010d9e2 2507 else {
QL 9:ca2e6010d9e2 2508 glbFilter_[rec >> 3] |=
QL 9:ca2e6010d9e2 2509 static_cast<uint8_t>(1U << (rec & static_cast<uint8_t>(0x07)));
QL 9:ca2e6010d9e2 2510 }
QL 9:ca2e6010d9e2 2511 }
QL 9:ca2e6010d9e2 2512 //............................................................................
QL 9:ca2e6010d9e2 2513 void QS::filterOff(uint8_t const rec) {
QL 9:ca2e6010d9e2 2514 if (rec == QS_ALL_RECORDS) {
QL 9:ca2e6010d9e2 2515 uint8_t i;
QL 9:ca2e6010d9e2 2516 for (i = static_cast<uint8_t>(0);
QL 9:ca2e6010d9e2 2517 i < static_cast<uint8_t>(sizeof(glbFilter_));
QL 9:ca2e6010d9e2 2518 ++i)
QL 9:ca2e6010d9e2 2519 {
QL 9:ca2e6010d9e2 2520 glbFilter_[i] = static_cast<uint8_t>(0);
QL 9:ca2e6010d9e2 2521 }
QL 9:ca2e6010d9e2 2522 }
QL 9:ca2e6010d9e2 2523 else {
QL 9:ca2e6010d9e2 2524 glbFilter_[rec >> 3] &= static_cast<uint8_t>(
QL 9:ca2e6010d9e2 2525 ~static_cast<uint8_t>((1U << (rec & static_cast<uint8_t>(0x07)))));
QL 9:ca2e6010d9e2 2526 }
QL 9:ca2e6010d9e2 2527 }
QL 9:ca2e6010d9e2 2528 //............................................................................
QL 9:ca2e6010d9e2 2529 void QS::begin(uint8_t const rec) {
QL 9:ca2e6010d9e2 2530 QS_chksum_ = static_cast<uint8_t>(0); // clear the checksum
QL 9:ca2e6010d9e2 2531 ++QS_seq_; // always increment the sequence number
QL 9:ca2e6010d9e2 2532 QS_INSERT_ESC_BYTE(QS_seq_) // store the sequence number
QL 9:ca2e6010d9e2 2533 QS_INSERT_ESC_BYTE(rec) // store the record ID
QL 9:ca2e6010d9e2 2534 }
QL 9:ca2e6010d9e2 2535 //............................................................................
QL 9:ca2e6010d9e2 2536 void QS::end(void) {
QL 9:ca2e6010d9e2 2537 QS_INSERT_CHKSUM_BYTE()
QL 9:ca2e6010d9e2 2538 QS_INSERT_BYTE(QS_FRAME)
QL 9:ca2e6010d9e2 2539 if (QS_used_ > QS_end_) { // overrun over the old data?
QL 9:ca2e6010d9e2 2540 QS_tail_ = QS_head_; // shift the tail to the old data
QL 9:ca2e6010d9e2 2541 QS_used_ = QS_end_; // the whole buffer is used
QL 9:ca2e6010d9e2 2542 }
QL 9:ca2e6010d9e2 2543 }
QL 9:ca2e6010d9e2 2544 //............................................................................
QL 9:ca2e6010d9e2 2545 void QS::u8(uint8_t const format, uint8_t const d) {
QL 9:ca2e6010d9e2 2546 QS_INSERT_ESC_BYTE(format)
QL 9:ca2e6010d9e2 2547 QS_INSERT_ESC_BYTE(d)
QL 9:ca2e6010d9e2 2548 }
QL 9:ca2e6010d9e2 2549 //............................................................................
QL 9:ca2e6010d9e2 2550 void QS::u16(uint8_t const format, uint16_t d) {
QL 9:ca2e6010d9e2 2551 QS_INSERT_ESC_BYTE(format)
QL 9:ca2e6010d9e2 2552 QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
QL 9:ca2e6010d9e2 2553 d >>= 8;
QL 9:ca2e6010d9e2 2554 QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
QL 9:ca2e6010d9e2 2555 }
QL 9:ca2e6010d9e2 2556 //............................................................................
QL 9:ca2e6010d9e2 2557 void QS::u32(uint8_t const format, uint32_t d) {
QL 9:ca2e6010d9e2 2558 QS_INSERT_ESC_BYTE(format)
QL 9:ca2e6010d9e2 2559 QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
QL 9:ca2e6010d9e2 2560 d >>= 8;
QL 9:ca2e6010d9e2 2561 QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
QL 9:ca2e6010d9e2 2562 d >>= 8;
QL 9:ca2e6010d9e2 2563 QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
QL 9:ca2e6010d9e2 2564 d >>= 8;
QL 9:ca2e6010d9e2 2565 QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
QL 9:ca2e6010d9e2 2566 }
QL 9:ca2e6010d9e2 2567
QL 9:ca2e6010d9e2 2568 QP_END_
QL 9:ca2e6010d9e2 2569
QL 9:ca2e6010d9e2 2570
QL 9:ca2e6010d9e2 2571 // "qs_.cpp" =================================================================
QL 9:ca2e6010d9e2 2572 /// \brief QS functions for internal use inside QP components
QL 9:ca2e6010d9e2 2573
QL 9:ca2e6010d9e2 2574 QP_BEGIN_
QL 9:ca2e6010d9e2 2575
QL 9:ca2e6010d9e2 2576 //............................................................................
QL 9:ca2e6010d9e2 2577 void const *QS::smObj_; // local state machine for QEP filter
QL 9:ca2e6010d9e2 2578 void const *QS::aoObj_; // local active object for QF filter
QL 9:ca2e6010d9e2 2579 void const *QS::mpObj_; // local event pool for QF filter
QL 9:ca2e6010d9e2 2580 void const *QS::eqObj_; // local raw queue for QF filter
QL 9:ca2e6010d9e2 2581 void const *QS::teObj_; // local time event for QF filter
QL 9:ca2e6010d9e2 2582 void const *QS::apObj_; // local object Application filter
QL 9:ca2e6010d9e2 2583
QL 9:ca2e6010d9e2 2584 QSTimeCtr QS::tickCtr_; // tick counter for the QS_QF_TICK record
QL 9:ca2e6010d9e2 2585
QL 9:ca2e6010d9e2 2586 //............................................................................
QL 9:ca2e6010d9e2 2587 void QS::u8_(uint8_t const d) {
QL 9:ca2e6010d9e2 2588 QS_INSERT_ESC_BYTE(d)
QL 9:ca2e6010d9e2 2589 }
QL 9:ca2e6010d9e2 2590 //............................................................................
QL 9:ca2e6010d9e2 2591 void QS::u16_(uint16_t d) {
QL 9:ca2e6010d9e2 2592 QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
QL 9:ca2e6010d9e2 2593 d >>= 8;
QL 9:ca2e6010d9e2 2594 QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
QL 9:ca2e6010d9e2 2595 }
QL 9:ca2e6010d9e2 2596 //............................................................................
QL 9:ca2e6010d9e2 2597 void QS::u32_(uint32_t d) {
QL 9:ca2e6010d9e2 2598 QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
QL 9:ca2e6010d9e2 2599 d >>= 8;
QL 9:ca2e6010d9e2 2600 QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
QL 9:ca2e6010d9e2 2601 d >>= 8;
QL 9:ca2e6010d9e2 2602 QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
QL 9:ca2e6010d9e2 2603 d >>= 8;
QL 9:ca2e6010d9e2 2604 QS_INSERT_ESC_BYTE(static_cast<uint8_t>(d))
QL 9:ca2e6010d9e2 2605 }
QL 9:ca2e6010d9e2 2606 //............................................................................
QL 9:ca2e6010d9e2 2607 void QS::str_(char_t const *s) {
QL 9:ca2e6010d9e2 2608 uint8_t b = static_cast<uint8_t>(*s);
QL 9:ca2e6010d9e2 2609 while (b != static_cast<uint8_t>(0)) {
QL 9:ca2e6010d9e2 2610 // ASCII characters don't need escaping
QL 9:ca2e6010d9e2 2611 QS_chksum_ = static_cast<uint8_t>(QS_chksum_ + b);
QL 9:ca2e6010d9e2 2612 QS_INSERT_BYTE(b)
QL 9:ca2e6010d9e2 2613 ++s;
QL 9:ca2e6010d9e2 2614 b = static_cast<uint8_t>(*s);
QL 9:ca2e6010d9e2 2615 }
QL 9:ca2e6010d9e2 2616 QS_INSERT_BYTE(static_cast<uint8_t>(0))
QL 9:ca2e6010d9e2 2617 }
QL 9:ca2e6010d9e2 2618 //............................................................................
QL 9:ca2e6010d9e2 2619 void QS::str_ROM_(char_t const Q_ROM * Q_ROM_VAR s) {
QL 9:ca2e6010d9e2 2620 uint8_t b = static_cast<uint8_t>(Q_ROM_BYTE(*s));
QL 9:ca2e6010d9e2 2621 while (b != static_cast<uint8_t>(0)) {
QL 9:ca2e6010d9e2 2622 // ASCII characters don't need escaping
QL 9:ca2e6010d9e2 2623 QS_chksum_ = static_cast<uint8_t>(QS_chksum_ + b);
QL 9:ca2e6010d9e2 2624 QS_INSERT_BYTE(b)
QL 9:ca2e6010d9e2 2625 ++s;
QL 9:ca2e6010d9e2 2626 b = static_cast<uint8_t>(Q_ROM_BYTE(*s));
QL 9:ca2e6010d9e2 2627 }
QL 9:ca2e6010d9e2 2628 QS_INSERT_BYTE(static_cast<uint8_t>(0))
QL 9:ca2e6010d9e2 2629 }
QL 9:ca2e6010d9e2 2630
QL 9:ca2e6010d9e2 2631 QP_END_
QL 9:ca2e6010d9e2 2632
QL 9:ca2e6010d9e2 2633 // "qs_blk.cpp" ==============================================================
QL 9:ca2e6010d9e2 2634 /// \brief QS::getBlock() implementation
QL 9:ca2e6010d9e2 2635
QL 9:ca2e6010d9e2 2636 QP_BEGIN_
QL 9:ca2e6010d9e2 2637
QL 9:ca2e6010d9e2 2638 //............................................................................
QL 9:ca2e6010d9e2 2639 // get up to *pn bytes of contiguous memory
QL 9:ca2e6010d9e2 2640 uint8_t const *QS::getBlock(uint16_t * const pNbytes) {
QL 9:ca2e6010d9e2 2641 uint8_t *block;
QL 9:ca2e6010d9e2 2642 if (QS_used_ == static_cast<QSCtr>(0)) {
QL 9:ca2e6010d9e2 2643 *pNbytes = static_cast<uint16_t>(0);
QL 9:ca2e6010d9e2 2644 block = static_cast<uint8_t *>(0); // no bytes to return right now
QL 9:ca2e6010d9e2 2645 }
QL 9:ca2e6010d9e2 2646 else {
QL 9:ca2e6010d9e2 2647 QSCtr n = static_cast<QSCtr>(QS_end_ - QS_tail_);
QL 9:ca2e6010d9e2 2648 if (n > QS_used_) {
QL 9:ca2e6010d9e2 2649 n = QS_used_;
QL 9:ca2e6010d9e2 2650 }
QL 9:ca2e6010d9e2 2651 if (n > static_cast<QSCtr>(*pNbytes)) {
QL 9:ca2e6010d9e2 2652 n = static_cast<QSCtr>(*pNbytes);
QL 9:ca2e6010d9e2 2653 }
QL 9:ca2e6010d9e2 2654 *pNbytes = static_cast<uint16_t>(n);
QL 9:ca2e6010d9e2 2655 QS_used_ = static_cast<QSCtr>(QS_used_ - n);
QL 9:ca2e6010d9e2 2656 QSCtr t = QS_tail_;
QL 9:ca2e6010d9e2 2657 QS_tail_ = static_cast<QSCtr>(QS_tail_ + n);
QL 9:ca2e6010d9e2 2658 if (QS_tail_ == QS_end_) {
QL 9:ca2e6010d9e2 2659 QS_tail_ = static_cast<QSCtr>(0);
QL 9:ca2e6010d9e2 2660 }
QL 9:ca2e6010d9e2 2661 block = &QS_PTR_AT_(t);
QL 9:ca2e6010d9e2 2662 }
QL 9:ca2e6010d9e2 2663 return block;
QL 9:ca2e6010d9e2 2664 }
QL 9:ca2e6010d9e2 2665
QL 9:ca2e6010d9e2 2666 QP_END_
QL 9:ca2e6010d9e2 2667
QL 9:ca2e6010d9e2 2668 // "qs_byte.cpp" =============================================================
QL 9:ca2e6010d9e2 2669 /// \brief QS::getByte() implementation
QL 9:ca2e6010d9e2 2670
QL 9:ca2e6010d9e2 2671 QP_BEGIN_
QL 9:ca2e6010d9e2 2672
QL 9:ca2e6010d9e2 2673 //............................................................................
QL 9:ca2e6010d9e2 2674 uint16_t QS::getByte(void) {
QL 9:ca2e6010d9e2 2675 uint16_t ret;
QL 9:ca2e6010d9e2 2676 if (QS_used_ == static_cast<QSCtr>(0)) {
QL 9:ca2e6010d9e2 2677 ret = QS_EOD; // set End-Of-Data
QL 9:ca2e6010d9e2 2678 }
QL 9:ca2e6010d9e2 2679 else {
QL 9:ca2e6010d9e2 2680 ret = static_cast<uint16_t>(QS_PTR_AT_(QS_tail_)); // byte to return
QL 9:ca2e6010d9e2 2681 ++QS_tail_; // advance the tail
QL 9:ca2e6010d9e2 2682 if (QS_tail_ == QS_end_) { // tail wrap around?
QL 9:ca2e6010d9e2 2683 QS_tail_ = static_cast<QSCtr>(0);
QL 9:ca2e6010d9e2 2684 }
QL 9:ca2e6010d9e2 2685 --QS_used_; // one less byte used
QL 9:ca2e6010d9e2 2686 }
QL 9:ca2e6010d9e2 2687 return ret; // return the byte or EOD
QL 9:ca2e6010d9e2 2688 }
QL 9:ca2e6010d9e2 2689
QL 9:ca2e6010d9e2 2690 QP_END_
QL 9:ca2e6010d9e2 2691
QL 9:ca2e6010d9e2 2692
QL 9:ca2e6010d9e2 2693 // "qs_f32.cpp" ==============================================================
QL 9:ca2e6010d9e2 2694 /// \brief QS::f32() implementation
QL 9:ca2e6010d9e2 2695
QL 9:ca2e6010d9e2 2696 QP_BEGIN_
QL 9:ca2e6010d9e2 2697
QL 9:ca2e6010d9e2 2698 //............................................................................
QL 9:ca2e6010d9e2 2699 void QS::f32(uint8_t const format, float32_t const d) {
QL 9:ca2e6010d9e2 2700 union F32Rep {
QL 9:ca2e6010d9e2 2701 float32_t f;
QL 9:ca2e6010d9e2 2702 uint32_t u;
QL 9:ca2e6010d9e2 2703 } fu32;
QL 9:ca2e6010d9e2 2704 fu32.f = d;
QL 9:ca2e6010d9e2 2705
QL 9:ca2e6010d9e2 2706 QS_INSERT_ESC_BYTE(format)
QL 9:ca2e6010d9e2 2707 QS_INSERT_ESC_BYTE(static_cast<uint8_t>(fu32.u))
QL 9:ca2e6010d9e2 2708 fu32.u >>= 8;
QL 9:ca2e6010d9e2 2709 QS_INSERT_ESC_BYTE(static_cast<uint8_t>(fu32.u))
QL 9:ca2e6010d9e2 2710 fu32.u >>= 8;
QL 9:ca2e6010d9e2 2711 QS_INSERT_ESC_BYTE(static_cast<uint8_t>(fu32.u))
QL 9:ca2e6010d9e2 2712 fu32.u >>= 8;
QL 9:ca2e6010d9e2 2713 QS_INSERT_ESC_BYTE(static_cast<uint8_t>(fu32.u))
QL 9:ca2e6010d9e2 2714 }
QL 9:ca2e6010d9e2 2715
QL 9:ca2e6010d9e2 2716 QP_END_
QL 9:ca2e6010d9e2 2717
QL 9:ca2e6010d9e2 2718
QL 9:ca2e6010d9e2 2719 // "qs_mem.cpp" ==============================================================
QL 9:ca2e6010d9e2 2720 /// \brief QS::mem() implementation
QL 9:ca2e6010d9e2 2721
QL 9:ca2e6010d9e2 2722 QP_BEGIN_
QL 9:ca2e6010d9e2 2723
QL 9:ca2e6010d9e2 2724 //............................................................................
QL 9:ca2e6010d9e2 2725 void QS::mem(uint8_t const *blk, uint8_t size) {
QL 9:ca2e6010d9e2 2726 QS_INSERT_BYTE(static_cast<uint8_t>(QS_MEM_T))
QL 9:ca2e6010d9e2 2727 QS_chksum_ =
QL 9:ca2e6010d9e2 2728 static_cast<uint8_t>(QS_chksum_ + static_cast<uint8_t>(QS_MEM_T));
QL 9:ca2e6010d9e2 2729 QS_INSERT_ESC_BYTE(size)
QL 9:ca2e6010d9e2 2730 while (size != static_cast<uint8_t>(0)) {
QL 9:ca2e6010d9e2 2731 QS_INSERT_ESC_BYTE(*blk)
QL 9:ca2e6010d9e2 2732 ++blk;
QL 9:ca2e6010d9e2 2733 --size;
QL 9:ca2e6010d9e2 2734 }
QL 9:ca2e6010d9e2 2735 }
QL 9:ca2e6010d9e2 2736
QL 9:ca2e6010d9e2 2737 QP_END_
QL 9:ca2e6010d9e2 2738
QL 9:ca2e6010d9e2 2739
QL 9:ca2e6010d9e2 2740 // "qs_str.cpp" ==============================================================
QL 9:ca2e6010d9e2 2741 /// \brief QS::str() and QS::str_ROM() implementation
QL 9:ca2e6010d9e2 2742
QL 9:ca2e6010d9e2 2743 QP_BEGIN_
QL 9:ca2e6010d9e2 2744
QL 9:ca2e6010d9e2 2745 //............................................................................
QL 9:ca2e6010d9e2 2746 void QS::str(char_t const *s) {
QL 9:ca2e6010d9e2 2747 uint8_t b = static_cast<uint8_t>(*s);
QL 9:ca2e6010d9e2 2748 QS_INSERT_BYTE(static_cast<uint8_t>(QS_STR_T))
QL 9:ca2e6010d9e2 2749 QS_chksum_ =
QL 9:ca2e6010d9e2 2750 static_cast<uint8_t>(QS_chksum_ + static_cast<uint8_t>(QS_STR_T));
QL 9:ca2e6010d9e2 2751 while (b != static_cast<uint8_t>(0)) {
QL 9:ca2e6010d9e2 2752 // ASCII characters don't need escaping
QL 9:ca2e6010d9e2 2753 QS_INSERT_BYTE(b)
QL 9:ca2e6010d9e2 2754 QS_chksum_ = static_cast<uint8_t>(QS_chksum_ + b);
QL 9:ca2e6010d9e2 2755 ++s;
QL 9:ca2e6010d9e2 2756 b = static_cast<uint8_t>(*s);
QL 9:ca2e6010d9e2 2757 }
QL 9:ca2e6010d9e2 2758 QS_INSERT_BYTE(static_cast<uint8_t>(0))
QL 9:ca2e6010d9e2 2759 }
QL 9:ca2e6010d9e2 2760 //............................................................................
QL 9:ca2e6010d9e2 2761 void QS::str_ROM(char_t const Q_ROM * Q_ROM_VAR s) {
QL 9:ca2e6010d9e2 2762 uint8_t b = static_cast<uint8_t>(Q_ROM_BYTE(*s));
QL 9:ca2e6010d9e2 2763 QS_INSERT_BYTE(static_cast<uint8_t>(QS_STR_T))
QL 9:ca2e6010d9e2 2764 QS_chksum_ =
QL 9:ca2e6010d9e2 2765 static_cast<uint8_t>(QS_chksum_ + static_cast<uint8_t>(QS_STR_T));
QL 9:ca2e6010d9e2 2766 while (b != static_cast<uint8_t>(0)) {
QL 9:ca2e6010d9e2 2767 // ASCII characters don't need escaping
QL 9:ca2e6010d9e2 2768 QS_INSERT_BYTE(b)
QL 9:ca2e6010d9e2 2769 QS_chksum_ = static_cast<uint8_t>(QS_chksum_ + b);
QL 9:ca2e6010d9e2 2770 ++s;
QL 9:ca2e6010d9e2 2771 b = static_cast<uint8_t>(Q_ROM_BYTE(*s));
QL 9:ca2e6010d9e2 2772 }
QL 9:ca2e6010d9e2 2773 QS_INSERT_BYTE(static_cast<uint8_t>(0))
QL 9:ca2e6010d9e2 2774 }
QL 9:ca2e6010d9e2 2775
QL 9:ca2e6010d9e2 2776 QP_END_
QL 9:ca2e6010d9e2 2777
QL 9:ca2e6010d9e2 2778 #endif // Q_SPY