QP/C  8.0.4
Real-Time Event Framework
Loading...
Searching...
No Matches
qp.h
Go to the documentation of this file.
1//============================================================================
2// QP/C Real-Time Event Framework (RTEF)
3//
4// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
5//
6// Q u a n t u m L e a P s
7// ------------------------
8// Modern Embedded Software
9//
10// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
11//
12// This software is dual-licensed under the terms of the open-source GNU
13// General Public License (GPL) or under the terms of one of the closed-
14// source Quantum Leaps commercial licenses.
15//
16// Redistributions in source code must retain this top-level comment block.
17// Plagiarizing this software to sidestep the license obligations is illegal.
18//
19// NOTE:
20// The GPL does NOT permit the incorporation of this code into proprietary
21// programs. Please contact Quantum Leaps for commercial licensing options,
22// which expressly supersede the GPL and are designed explicitly for
23// closed-source distribution.
24//
25// Quantum Leaps contact information:
26// <www.state-machine.com/licensing>
27// <info@state-machine.com>
28//============================================================================
29#ifndef QP_H_
30#define QP_H_
31
32//============================================================================
33#define QP_VERSION_STR "8.0.4"
34#define QP_VERSION 804U
35// <VER>=804 <DATE>=250611
36#define QP_RELEASE 0x6A9FC8ABU
37
38//============================================================================
39// default configuration settings
40//! @cond INTERNAL
41
42#ifndef Q_SIGNAL_SIZE
43#define Q_SIGNAL_SIZE 2U
44#endif
45
46#ifndef QF_MAX_ACTIVE
47#define QF_MAX_ACTIVE 32U
48#endif
49
50#if (QF_MAX_ACTIVE > 64U)
51#error QF_MAX_ACTIVE exceeds the maximum of 64U;
52#endif
53
54#ifndef QF_MAX_TICK_RATE
55#define QF_MAX_TICK_RATE 1U
56#endif
57
58#if (QF_MAX_TICK_RATE > 15U)
59#error QF_MAX_TICK_RATE exceeds the maximum of 15U;
60#endif
61
62#ifndef QF_MAX_EPOOL
63#define QF_MAX_EPOOL 3U
64#endif
65
66#if (QF_MAX_EPOOL > 15U)
67#error QF_MAX_EPOOL exceeds the maximum of 15U;
68#endif
69
70#ifndef QF_TIMEEVT_CTR_SIZE
71#define QF_TIMEEVT_CTR_SIZE 4U
72#endif
73
74#if (QF_TIMEEVT_CTR_SIZE > 4U)
75#error QF_TIMEEVT_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U;
76#endif
77
78#ifndef QF_EVENT_SIZ_SIZE
79#define QF_EVENT_SIZ_SIZE 2U
80#endif
81
82#if (QF_EVENT_SIZ_SIZE > 4U)
83#error QF_EVENT_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U;
84#endif
85
86//! @endcond
87
88//============================================================================
89// global types/utilities
90
91typedef int int_t;
92typedef int enum_t;
93
94#define Q_UNUSED_PAR(par_) ((void)(par_))
95#define Q_DIM(array_) (sizeof(array_) / sizeof((array_)[0U]))
96#define Q_UINT2PTR_CAST(type_, uint_) ((type_ *)(uint_))
97
98//============================================================================
99extern char const QP_versionStr[24];
100
101// QSignal type
102#if (Q_SIGNAL_SIZE == 1U)
103 typedef uint8_t QSignal;
104#elif (Q_SIGNAL_SIZE == 2U)
105 typedef uint16_t QSignal;
106#elif (Q_SIGNAL_SIZE == 4U)
107 typedef uint32_t QSignal;
108#endif
109
110//============================================================================
111//! @class QEvt
112typedef struct QEvt {
113 QSignal sig; //!< @public @memberof QEvt
114 uint8_t poolNum_; //!< @private @memberof QEvt
115 uint8_t volatile refCtr_; //!< @private @memberof QEvt
116} QEvt;
117
118#define QEVT_INITIALIZER(sig_) { (QSignal)(sig_), 0x00U, 0xE0U }
119//! @public @memberof QEvt
120static inline void QEvt_ctor(QEvt * const me,
121 enum_t const sig)
122{
123 me->sig = (QSignal)sig;
124 me->poolNum_ = 0x00U;
125 me->refCtr_ = 0xE0U;
126}
127
128//! @public @memberof QEvt
129static inline QEvt * QEvt_init(QEvt * const me,
130 uint8_t const dummy)
131{
132 Q_UNUSED_PAR(dummy);
133 return me;
134}
135
136typedef QEvt const * QEvtPtr;
137
138#define QEVT_DYNAMIC ((uint8_t)0)
139#define Q_EVT_CAST(class_) ((class_ const *)(e))
140
141//============================================================================
142// QEP (hierarchical event processor) types
143
144typedef uint_fast8_t QState;
145typedef QState (*QStateHandler)(void * const me, QEvt const * const e);
146typedef QState (*QActionHandler)(void * const me);
147
148struct QXThread; // forward declaration
149typedef void (* QXThreadHandler )(struct QXThread * const me);
150
151typedef struct QMState {
152 struct QMState const *superstate; //!< @private @memberof QMState
153 QStateHandler const stateHandler; //!< @private @memberof QMState
154 QActionHandler const entryAction; //!< @private @memberof QMState
155 QActionHandler const exitAction; //!< @private @memberof QMState
156 QActionHandler const initAction; //!< @private @memberof QMState
157} QMState;
158
159typedef struct QMTranActTable {
160 QMState const *target; //!< @private @memberof QMTranActTable
161 QActionHandler const act[1]; //!< @private @memberof QMTranActTable
163
164union QAsmAttr {
165 QStateHandler fun; //!< @private @memberof QAsmAttr
166 QActionHandler act; //!< @private @memberof QAsmAttr
167 QXThreadHandler thr; //!< @private @memberof QAsmAttr
168 QMTranActTable const *tatbl; //!< @private @memberof QAsmAttr
169 struct QMState const *obj; //!< @private @memberof QAsmAttr
170 uintptr_t uint; //!< @private @memberof QAsmAttr
171};
172
173#define Q_STATE_CAST(handler_) ((QStateHandler)(handler_))
174#define Q_ACTION_CAST(action_) ((QActionHandler)(action_))
175#define Q_ACTION_NULL ((QActionHandler)0)
176
177//============================================================================
178//! @class QAsm
179typedef struct {
180 struct QAsmVtable const * vptr; //!< @protected @memberof QAsm
181 union QAsmAttr state; //!< @protected @memberof QAsm
182 union QAsmAttr temp; //!< @protected @memberof QAsm
183} QAsm;
184
185// All possible values returned from state/action handlers
186// NOTE: The ordering is important for algorithmic correctness.
187#define Q_RET_SUPER ((QState)0U)
188#define Q_RET_UNHANDLED ((QState)1U)
189
190// handled and do not need to "bubble up"
191#define Q_RET_HANDLED ((QState)2U)
192#define Q_RET_IGNORED ((QState)3U)
193
194// entry/exit
195#define Q_RET_ENTRY ((QState)4U)
196#define Q_RET_EXIT ((QState)5U)
197
198// no side effects
199#define Q_RET_NULL ((QState)6U)
200
201// transitions need to execute transition-action table in ::QMsm
202#define Q_RET_TRAN ((QState)7U)
203#define Q_RET_TRAN_INIT ((QState)8U)
204
205// transitions that additionally clobber me->state
206#define Q_RET_TRAN_HIST ((QState)9U)
207
208// Reserved signals by the QP-framework.
209#define Q_EMPTY_SIG ((QSignal)0U)
210#define Q_ENTRY_SIG ((QSignal)1U)
211#define Q_EXIT_SIG ((QSignal)2U)
212#define Q_INIT_SIG ((QSignal)3U)
213#define Q_USER_SIG ((enum_t)4)
214
215//! @protected @memberof QAsm
216static inline void QAsm_ctor(QAsm * const me) {
217 me->vptr = (struct QAsmVtable *)0;
218 me->state.fun = (QStateHandler)0;
219 me->temp.fun = (QStateHandler)0;
220}
221
223 void (*init)(QAsm * const me, void const * const e,
224 uint_fast8_t const qsId);
225 void (*dispatch)(QAsm * const me, QEvt const * const e,
226 uint_fast8_t const qsId);
227 bool (*isIn)(QAsm * const me, QStateHandler const stateHndl);
228#ifdef Q_SPY
230#endif // Q_SPY
231};
232
233#ifdef Q_SPY
234 #define QASM_INIT(me_, par_, qsId_) \
235 (*((QAsm *)(me_))->vptr->init)((QAsm *)(me_), (par_), (qsId_))
236 #define QASM_DISPATCH(me_, e_, qsId_) \
237 (*((QAsm *)(me_))->vptr->dispatch)((QAsm *)(me_), (e_), (qsId_))
238 #define QASM_IS_IN(me_, stateHndl_) \
239 (*((QAsm *)(me_))->vptr->isIn)((QAsm *)(me_), (stateHndl_))
240#else
241 #define QASM_INIT(me_, par_, dummy) \
242 (*((QAsm *)(me_))->vptr->init)((QAsm *)(me_), (par_), 0U)
243 #define QASM_DISPATCH(me_, e_, dummy) \
244 (*((QAsm *)(me_))->vptr->dispatch)((QAsm *)(me_), (e_), 0U)
245#endif // ndef Q_SPY
246
247#define Q_ASM_UPCAST(ptr_) ((QAsm *)(ptr_))
248
249//============================================================================
250//! @class QHsm
251//! @extends QAsm
252typedef struct {
253 QAsm super; //!< @protected @memberof QHsm
254} QHsm;
255
256//! @protected @memberof QHsm
257void QHsm_ctor(QHsm * const me,
258 QStateHandler const initial);
259
260//! @private @memberof QHsm
261void QHsm_init_(
262 QAsm * const me,
263 void const * const e,
264 uint_fast8_t const qsId);
265
266//! @private @memberof QHsm
267void QHsm_dispatch_(
268 QAsm * const me,
269 QEvt const * const e,
270 uint_fast8_t const qsId);
271
272//! @private @memberof QHsm
273bool QHsm_isIn_(
274 QAsm * const me,
275 QStateHandler const stateHndl);
276
277#ifdef Q_SPY
278//! @private @memberof QHsm
279QStateHandler QHsm_getStateHandler_(QAsm * const me);
280#endif // def Q_SPY
281
282//! @protected @memberof QHsm
283QState QHsm_top(QHsm const * const me,
284 QEvt const * const e);
285
286//! @public @memberof QHsm
287static inline QStateHandler QHsm_state(QHsm const * const me) {
288 return me->super.state.fun;
289}
290
291//! @public @memberof QHsm
292QStateHandler QHsm_childState(QHsm * const me,
293 QStateHandler const parentHndl);
294
295#define Q_HSM_UPCAST(ptr_) ((QHsm *)(ptr_))
296
297#define Q_TRAN(target_) \
298 ((Q_ASM_UPCAST(me))->temp.fun = Q_STATE_CAST(target_), \
299 (QState)Q_RET_TRAN)
300#define Q_TRAN_HIST(hist_) \
301 ((Q_ASM_UPCAST(me))->temp.fun = (hist_), \
302 (QState)Q_RET_TRAN_HIST)
303#define Q_SUPER(super_) \
304 ((Q_ASM_UPCAST(me))->temp.fun = Q_STATE_CAST(super_), \
305 (QState)Q_RET_SUPER)
306#define Q_HANDLED() ((QState)Q_RET_HANDLED)
307#define Q_UNHANDLED() ((QState)Q_RET_UNHANDLED)
308
309//============================================================================
310//! @class QMsm
311//! @extends QAsm
312typedef struct {
313 QAsm super; //!< @protected @memberof QMsm
314} QMsm;
315
316//! @protected @memberof QMsm
317void QMsm_ctor(QMsm * const me,
318 QStateHandler const initial);
319
320//! @private @memberof QMsm
321void QMsm_init_(
322 QAsm * const me,
323 void const * const e,
324 uint_fast8_t const qsId);
325
326//! @private @memberof QMsm
327void QMsm_dispatch_(
328 QAsm * const me,
329 QEvt const * const e,
330 uint_fast8_t const qsId);
331
332//! @private @memberof QMsm
333bool QMsm_isIn_(
334 QAsm * const me,
335 QStateHandler const stateHndl);
336
337#ifdef Q_SPY
338//! @public @memberof QMsm
340#endif // def Q_SPY
341
342//! @public @memberof QMsm
343static inline QMState const * QMsm_stateObj(QMsm const * const me) {
344 return me->super.state.obj;
345}
346
347//! @public @memberof QMsm
348QMState const * QMsm_childStateObj(QMsm const * const me,
349 QMState const * const parent);
350//============================================================================
351// QEP-macros
352
353#define Q_MSM_UPCAST(ptr_) ((QMsm *)(ptr_))
354#ifdef Q_SPY
355 #define QM_ENTRY(state_) \
356 ((Q_ASM_UPCAST(me))->temp.obj = (state_), (QState)Q_RET_ENTRY)
357 #define QM_EXIT(state_) \
358 ((Q_ASM_UPCAST(me))->temp.obj = (state_), (QState)Q_RET_EXIT)
359#else
360 #define QM_ENTRY(dummy) ((QState)Q_RET_ENTRY)
361 #define QM_EXIT(dummy) ((QState)Q_RET_EXIT)
362#endif // ndef Q_SPY
363
364#define QM_TRAN(tatbl_) ((Q_ASM_UPCAST(me))->temp.tatbl \
365 = (struct QMTranActTable const *)(tatbl_), (QState)Q_RET_TRAN)
366
367#define QM_TRAN_INIT(tatbl_) ((Q_ASM_UPCAST(me))->temp.tatbl \
368 = (struct QMTranActTable const *)(tatbl_), (QState)Q_RET_TRAN_INIT)
369
370#define QM_TRAN_HIST(history_, tatbl_) \
371 ((((Q_ASM_UPCAST(me))->state.obj = (history_)), \
372 ((Q_ASM_UPCAST(me))->temp.tatbl = \
373 (struct QMTranActTable const *)(tatbl_))), (QState)Q_RET_TRAN_HIST)
374
375#define QM_HANDLED() ((QState)Q_RET_HANDLED)
376#define QM_UNHANDLED() ((QState)Q_RET_UNHANDLED)
377#define QM_SUPER() ((QState)Q_RET_SUPER)
378#define QM_STATE_NULL ((QMState *)0)
379
380//============================================================================
381// QF (active object framework) types
382
383typedef uint16_t QPrioSpec;
384
385#if (QF_TIMEEVT_CTR_SIZE == 1U)
386 typedef uint8_t QTimeEvtCtr;
387#elif (QF_TIMEEVT_CTR_SIZE == 2U)
388 typedef uint16_t QTimeEvtCtr;
389#elif (QF_TIMEEVT_CTR_SIZE == 4U)
390 typedef uint32_t QTimeEvtCtr;
391#endif // (QF_TIMEEVT_CTR_SIZE == 4U)
392
393#if (QF_MAX_ACTIVE <= 8U)
394 typedef uint8_t QPSetBits;
395#elif (8U < QF_MAX_ACTIVE) && (QF_MAX_ACTIVE <= 16U)
396 typedef uint16_t QPSetBits;
397#elif (16U < QF_MAX_ACTIVE)
398 typedef uint32_t QPSetBits;
399#endif // (16U < QF_MAX_ACTIVE)
400
401#ifndef QF_LOG2
402 uint_fast8_t QF_LOG2(QPSetBits const bitmask);
403#endif // ndef QF_LOG2
404
405//============================================================================
406//! @class QPSet
407typedef struct {
408 //! @private @memberof QPSet
409 QPSetBits bits[((QF_MAX_ACTIVE + (8U*sizeof(QPSetBits))) - 1U)
410 / (8U*sizeof(QPSetBits))];
411} QPSet;
412
413//! @public @memberof QPSet
414static inline void QPSet_setEmpty(QPSet * const me) {
415 me->bits[0] = 0U;
416#if (QF_MAX_ACTIVE > 32)
417 me->bits[1] = 0U;
418#endif
419}
420
421//! @public @memberof QPSet
422static inline bool QPSet_isEmpty(QPSet const * const me) {
423#if (QF_MAX_ACTIVE <= 32U)
424 return (me->bits[0] == 0U);
425#else
426 return (me->bits[0] == 0U) ? (me->bits[1] == 0U) : false;
427#endif
428}
429
430//! @public @memberof QPSet
431static inline bool QPSet_notEmpty(QPSet const * const me) {
432#if (QF_MAX_ACTIVE <= 32U)
433 return (me->bits[0] != 0U);
434#else
435 return (me->bits[0] != 0U) ? true : (me->bits[1] != 0U);
436#endif
437}
438
439//! @public @memberof QPSet
440static inline bool QPSet_hasElement(QPSet const * const me,
441 uint_fast8_t const n)
442{
443#if (QF_MAX_ACTIVE <= 32U)
444 return (me->bits[0] & ((QPSetBits)1U << (n - 1U))) != 0U;
445#else
446 return (n <= 32U)
447 ? ((me->bits[0] & ((QPSetBits)1U << (n - 1U))) != 0U)
448 : ((me->bits[1] & ((QPSetBits)1U << (n - 33U))) != 0U);
449#endif
450}
451
452//! @public @memberof QPSet
453static inline void QPSet_insert(QPSet * const me,
454 uint_fast8_t const n)
455{
456#if (QF_MAX_ACTIVE <= 32U)
457 me->bits[0] = (me->bits[0] | ((QPSetBits)1U << (n - 1U)));
458#else
459 if (n <= 32U) {
460 me->bits[0] = (me->bits[0] | ((QPSetBits)1U << (n - 1U)));
461 }
462 else {
463 me->bits[1] = (me->bits[1] | ((QPSetBits)1U << (n - 33U)));
464 }
465#endif
466}
467
468//! @public @memberof QPSet
469static inline void QPSet_remove(QPSet * const me,
470 uint_fast8_t const n)
471{
472#if (QF_MAX_ACTIVE <= 32U)
473 me->bits[0] = (me->bits[0] & (QPSetBits)(~((QPSetBits)1U << (n - 1U))));
474#else
475 if (n <= 32U) {
476 (me->bits[0] = (me->bits[0] & ~((QPSetBits)1U << (n - 1U))));
477 }
478 else {
479 (me->bits[1] = (me->bits[1] & ~((QPSetBits)1U << (n - 33U))));
480 }
481#endif
482}
483
484//! @public @memberof QPSet
485static inline uint_fast8_t QPSet_findMax(QPSet const * const me) {
486#if (QF_MAX_ACTIVE <= 32U)
487 return QF_LOG2(me->bits[0]);
488#else
489 return (me->bits[1] != 0U)
490 ? (QF_LOG2(me->bits[1]) + 32U)
491 : (QF_LOG2(me->bits[0]));
492#endif
493}
494
495//! @struct QSubscrList
496typedef struct {
497 QPSet set; //!< @private @memberof QSubscrList
499
500struct QEQueue; // forward declaration
501
502//============================================================================
503//! @class QActive
504//! @extends QAsm
505typedef struct QActive {
506 QAsm super; //!< @protected @memberof QActive
507 uint8_t prio; //!< @protected @memberof QActive
508 uint8_t pthre; //!< @protected @memberof QActive
509
510#ifdef QACTIVE_THREAD_TYPE
511 QACTIVE_THREAD_TYPE thread; //!< @protected @memberof QActive
512#endif
513
514#ifdef QACTIVE_OS_OBJ_TYPE
515 QACTIVE_OS_OBJ_TYPE osObject; //!< @protected @memberof QActive
516#endif
517
518#ifdef QACTIVE_EQUEUE_TYPE
519 QACTIVE_EQUEUE_TYPE eQueue; //!< @protected @memberof QActive
520#endif // def QACTIVE_EQUEUE_TYPE
521} QActive;
522
523//! @protected @memberof QActive
524void QActive_ctor(QActive * const me,
525 QStateHandler const initial);
526
527//! @public @memberof QActive
528void QActive_setAttr(QActive * const me,
529 uint32_t attr1,
530 void const * attr2);
531
532//! @public @memberof QActive
533void QActive_start(QActive * const me,
534 QPrioSpec const prioSpec,
535 QEvtPtr * const qSto,
536 uint_fast16_t const qLen,
537 void * const stkSto,
538 uint_fast16_t const stkSize,
539 void const * const par);
540
541#ifdef QACTIVE_CAN_STOP
542//! @protected @memberof QActive
543void QActive_stop(QActive * const me);
544#endif // def QACTIVE_CAN_STOP
545
546//! @private @memberof QActive
547void QActive_register_(QActive * const me);
548
549//! @private @memberof QActive
550void QActive_unregister_(QActive * const me);
551
552//! @private @memberof QActive
553bool QActive_post_(QActive * const me,
554 QEvt const * const e,
555 uint_fast16_t const margin,
556 void const * const sender);
557
558//! @private @memberof QActive
559void QActive_postLIFO_(QActive * const me,
560 QEvt const * const e);
561
562//! @private @memberof QActive
563QEvt const * QActive_get_(QActive * const me);
564
565//! @static @public @memberof QActive
567 QSubscrList * const subscrSto,
568 enum_t const maxSignal);
569
570//! @static @private @memberof QActive
572 QEvt const * const e,
573 void const * const sender,
574 uint_fast8_t const qsId);
575
576//! @static @public @memberof QActive
577uint_fast16_t QActive_getQueueMin(uint_fast8_t const prio);
578
579//! @protected @memberof QActive
580void QActive_subscribe(QActive const * const me,
581 enum_t const sig);
582
583//! @protected @memberof QActive
584void QActive_unsubscribe(QActive const * const me,
585 enum_t const sig);
586
587//! @protected @memberof QActive
588void QActive_unsubscribeAll(QActive const * const me);
589
590//! @protected @memberof QActive
591bool QActive_defer(QActive const * const me,
592 struct QEQueue * const eq,
593 QEvt const * const e);
594
595//! @protected @memberof QActive
596bool QActive_recall(QActive * const me,
597 struct QEQueue * const eq);
598
599//! @protected @memberof QActive
600uint_fast16_t QActive_flushDeferred(QActive const * const me,
601 struct QEQueue * const eq,
602 uint_fast16_t const num);
603
604//! @private @memberof QActive
605void QActive_evtLoop_(QActive * const me);
606
607//============================================================================
608//! @class QMActive
609//! @extends QActive
610typedef struct {
611 QActive super; //!< @protected @memberof QMActive
612} QMActive;
613
614//! @protected @memberof QMActive
615void QMActive_ctor(QMActive * const me,
616 QStateHandler const initial);
617
618//============================================================================
619//! @class QTimeEvt
620//! @extends QEvt
621typedef struct QTimeEvt {
622 QEvt super; //!< @protected @memberof QTimeEvt
623
624 struct QTimeEvt * volatile next; //!< @private @memberof QTimeEvt
625 void * act; //!< @private @memberof QTimeEvt
626 QTimeEvtCtr volatile ctr; //!< @private @memberof QTimeEvt
627 QTimeEvtCtr interval; //!< @private @memberof QTimeEvt
628 uint8_t tickRate; //!< @private @memberof QTimeEvt
629 uint8_t flags; //!< @private @memberof QTimeEvt
630} QTimeEvt;
631
632//! @public @memberof QTimeEvt
633void QTimeEvt_ctorX(QTimeEvt * const me,
634 QActive * const act,
635 enum_t const sig,
636 uint_fast8_t const tickRate);
637
638//! @public @memberof QTimeEvt
639void QTimeEvt_armX(QTimeEvt * const me,
640 uint32_t const nTicks,
641 uint32_t const interval);
642
643//! @public @memberof QTimeEvt
644bool QTimeEvt_disarm(QTimeEvt * const me);
645
646//! @public @memberof QTimeEvt
647bool QTimeEvt_rearm(QTimeEvt * const me,
648 uint32_t const nTicks);
649
650//! @public @memberof QTimeEvt
651bool QTimeEvt_wasDisarmed(QTimeEvt * const me);
652
653//! @public @memberof QTimeEvt
654QTimeEvtCtr QTimeEvt_currCtr(QTimeEvt const * const me);
655
656//! @static @private @memberof QTimeEvt
657void QTimeEvt_init(void);
658
659//! @static @private @memberof QTimeEvt
660void QTimeEvt_tick_(
661 uint_fast8_t const tickRate,
662 void const * const sender);
663
664//! @private @memberof QTimeEvt
666 QTimeEvt * const prev_link,
667 QActive const * const act,
668 uint_fast8_t const tickRate);
669
670#ifdef Q_UTEST
671 //! @static @private @memberof QTimeEvt
673 uint_fast8_t const tickRate,
674 void const * const sender);
675#endif // def Q_UTEST
676
677//! @static @public @memberof QTimeEvt
678bool QTimeEvt_noActive(uint_fast8_t const tickRate);
679
680//============================================================================
681//! @class QTicker
682//! @extends QActive
683typedef struct {
684 QActive super; //!< @protected @memberof QTicker
685} QTicker;
686
687//! @public @memberof QTicker
688void QTicker_ctor(QTicker * const me,
689 uint_fast8_t const tickRate);
690
691//! @private @memberof QTicker
692void QTicker_init_(
693 QAsm * const me,
694 void const * const par,
695 uint_fast8_t const qsId);
696
697//! @private @memberof QTicker
698void QTicker_dispatch_(
699 QAsm * const me,
700 QEvt const * const e,
701 uint_fast8_t const qsId);
702
703//! @private @memberof QTicker
704void QTicker_trig_(
705 QTicker * const me,
706 void const * const sender);
707
708//============================================================================
709// QF base facilities
710
711//! @static @public @memberof QF
712void QF_init(void);
713
714//! @static @public @memberof QF
715void QF_stop(void);
716
717//! @static @public @memberof QF
718int_t QF_run(void);
719
720//! @static @public @memberof QF
721void QF_onStartup(void);
722
723//! @static @public @memberof QF
724void QF_onCleanup(void);
725
726#ifdef QF_ON_CONTEXT_SW
727 //! @static @public @memberof QF
729 QActive * prev,
730 QActive * next);
731#endif // def QF_ON_CONTEXT_SW
732
733#define Q_PRIO(prio_, pthre_) ((QPrioSpec)((prio_) | ((pthre_) << 8U)))
734#define QF_NO_MARGIN ((uint_fast16_t)0xFFFFU)
735
736//============================================================================
737// QF dynamic memory facilities
738
739//! @static @public @memberof QF
741 void * const poolSto,
742 uint_fast32_t const poolSize,
743 uint_fast16_t const evtSize);
744
745//! @static @public @memberof QF
746uint_fast16_t QF_poolGetMaxBlockSize(void);
747
748//! @static @public @memberof QF
749uint_fast16_t QF_getPoolMin(uint_fast8_t const poolNum);
750
751//! @static @private @memberof QF
752QEvt * QF_newX_(
753 uint_fast16_t const evtSize,
754 uint_fast16_t const margin,
755 enum_t const sig);
756
757//! @static @public @memberof QF
758void QF_gc(QEvt const * const e);
759
760//! @static @private @memberof QF
761QEvt const * QF_newRef_(
762 QEvt const * const e,
763 void const * const evtRef);
764
765//! @static @private @memberof QF
766void QF_deleteRef_(void const * const evtRef);
767
768//! @static @public @memberof QF
769void QF_gcFromISR(QEvt const * const e);
770
771#ifdef QEVT_PAR_INIT
772 #define Q_NEW(evtT_, sig_, ...) \
773 (evtT_##_init((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \
774 QF_NO_MARGIN, (sig_)), __VA_ARGS__))
775 #define Q_NEW_X(evtT_, margin_, sig_, ...) \
776 (evtT_##_init((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \
777 (margin_), (sig_)), __VA_ARGS__))
778#else
779 #define Q_NEW(evtT_, sig_) \
780 ((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \
781 QF_NO_MARGIN, (enum_t)(sig_)))
782 #define Q_NEW_X(evtT_, margin_, sig_) \
783 ((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \
784 (margin_), (enum_t)(sig_)))
785#endif // QEVT_PAR_INIT
786
787#define Q_NEW_REF(evtRef_, evtT_) \
788 ((evtRef_) = (evtT_ const *)QF_newRef_(e, (evtRef_)))
789#define Q_DELETE_REF(evtRef_) do { \
790 QF_deleteRef_((evtRef_)); \
791 (evtRef_) = (void *)0; \
792} while (false)
793
794#ifdef Q_SPY
795 #define QACTIVE_POST(me_, e_, sender_) \
796 ((void)QActive_post_((me_), (e_), QF_NO_MARGIN, (sender_)))
797 #define QACTIVE_POST_X(me_, e_, margin_, sender_) \
798 (QActive_post_((me_), (e_), (margin_), (sender_)))
799 #define QACTIVE_PUBLISH(e_, sender_) \
800 (QActive_publish_((e_), (void const *)(sender_), (sender_)->prio))
801 #define QTIMEEVT_TICK_X(tickRate_, sender_) (QTimeEvt_tick_((tickRate_), (sender_)))
802 #define QTICKER_TRIG(ticker_, sender_) (QTicker_trig_((ticker_), (sender_)))
803#else
804 #define QACTIVE_POST(me_, e_, dummy) \
805 ((void)QActive_post_((me_), (e_), QF_NO_MARGIN, (void *)0))
806 #define QACTIVE_POST_X(me_, e_, margin_, dummy) \
807 (QActive_post_((me_), (e_), (margin_), (void *)0))
808 #define QACTIVE_PUBLISH(e_, dummy) (QActive_publish_((e_), (void *)0, 0U))
809 #define QTIMEEVT_TICK_X(tickRate_, dummy) (QTimeEvt_tick_((tickRate_), (void *)0))
810 #define QTICKER_TRIG(ticker_, sender_) (QTicker_trig_((ticker_), (void *)0))
811#endif // ndef Q_SPY
812
813#define QACTIVE_POST_LIFO(me_, e_) (QActive_postLIFO_((me_), (e_)))
814#define QTIMEEVT_TICK(sender_) QTIMEEVT_TICK_X(0U, (sender_))
815
816#ifndef QF_CRIT_EXIT_NOP
817 #define QF_CRIT_EXIT_NOP() ((void)0)
818#endif // ndef QF_CRIT_EXIT_NOP
819
820//============================================================================
821// memory protection facilities
822
823#ifdef QF_MEM_ISOLATE
824 #error Memory isolation not supported in this QP edition, need SafeQP
825#endif
826
827#endif // QP_H_
void QF_onStartup(void)
Startup QF callback.
void QF_poolInit(void *const poolSto, uint_fast32_t const poolSize, uint_fast16_t const evtSize)
Event pool initialization for dynamic allocation of events.
void QF_onCleanup(void)
Cleanup QF callback.
void QF_gc(QEvt const *const e)
Recycle a mutable (mutable) event.
Definition qf_dyn.c:189
uint_fast16_t QF_poolGetMaxBlockSize(void)
Obtain the block size of any registered event pools.
Definition qf_dyn.c:80
uint_fast16_t QF_getPoolMin(uint_fast8_t const poolNum)
Obtain the minimum of free entries of the given event pool.
Definition qf_dyn.c:96
void QF_onContextSw(QActive *prev, QActive *next)
QF context switch callback used in built-in kernels (QV/QK/QXK)
QEvt * QF_newX_(uint_fast16_t const evtSize, uint_fast16_t const margin, enum_t const sig)
Internal QF implementation of creating new mutable (dynamic) event.
Definition qf_dyn.c:114
void QF_gcFromISR(QEvt const *const e)
void QF_deleteRef_(void const *const evtRef)
Internal QF implementation of deleting event reference.
Definition qf_dyn.c:277
QEvt const * QF_newRef_(QEvt const *const e, void const *const evtRef)
Internal QF implementation of creating new event reference.
Definition qf_dyn.c:242
#define Q_UNUSED_PAR(par_)
Helper macro to clearly mark unused parameters of functions.
Definition qp.h:94
void(* QXThreadHandler)(struct QXThread *const me)
Pointer to an extended-thread handler function.
Definition qp.h:149
uint32_t QPSetBits
Bitmask for the internal representation of QPSet elements.
Definition qp.h:398
QState(* QStateHandler)(void *const me, QEvt const *const e)
Pointer to a state-handler function.
Definition qp.h:145
QEvt const * QEvtPtr
Pointer to const event instances passed around in QP Framework.
Definition qp.h:136
uint32_t QTimeEvtCtr
Data type to store the block-size defined based on the macro QF_TIMEEVT_CTR_SIZE.
Definition qp.h:390
uint_fast8_t QF_LOG2(QPSetBits const bitmask)
Log-base-2 calculation when hardware acceleration is NOT provided (QF_LOG2 not defined)
Definition qf_act.c:65
int int_t
Alias for assertion-ID numbers in QP assertions and return from QF_run()
Definition qp.h:91
int enum_t
Definition qp.h:92
uint_fast8_t QState
Type returned from state-handler functions.
Definition qp.h:144
char const QP_versionStr[24]
Definition qf_act.c:43
QState(* QActionHandler)(void *const me)
Pointer to an action-handler function.
Definition qp.h:146
uint16_t QSignal
The signal of event QEvt.
Definition qp.h:105
uint16_t QPrioSpec
Priority specification for Active Objects in QP.
Definition qp.h:383
#define QF_MAX_ACTIVE
Maximum # Active Objects in the system (1..64)
Definition qp_config.h:123
#define QACTIVE_OS_OBJ_TYPE
QActive "OS-object" type used in various QP/C ports.
Definition qp_port.h:30
#define QACTIVE_EQUEUE_TYPE
QActive event queue type used in various QP/C ports.
Definition qp_port.h:27
#define QACTIVE_THREAD_TYPE
QActive "thread" type used in various QP/C ports.
Definition qp_port.h:33
Active object class (based on the QHsm implementation strategy)
Definition qp.h:505
void QActive_unsubscribe(QActive const *const me, enum_t const sig)
Unsubscribes from the delivery of signal sig to the active object.
Definition qf_ps.c:188
QAsm super
Definition qp.h:506
void QActive_unregister_(QActive *const me)
Un-register the active object from the framework.
Definition qf_qact.c:116
QACTIVE_THREAD_TYPE thread
Port-dependent representation of the thread of the active object.
Definition qp.h:511
bool QActive_post_(QActive *const me, QEvt const *const e, uint_fast16_t const margin, void const *const sender)
Posts an event e directly to the event queue of the active object using the First-In-First-Out (FIFO)...
QEvt const * QActive_get_(QActive *const me)
Get an event from the event queue of an active object.
Definition qf_actq.c:202
void QActive_postLIFO_(QActive *const me, QEvt const *const e)
Posts an event e directly to the event queue of the active object using the Last-In-First-Out (LIFO) ...
Definition qf_actq.c:127
void QActive_ctor(QActive *const me, QStateHandler const initial)
QActive constructor (abstract base class)
bool QActive_defer(QActive const *const me, struct QEQueue *const eq, QEvt const *const e)
Defer an event to a given separate event queue.
void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2)
uint_fast16_t QActive_getQueueMin(uint_fast8_t const prio)
This function returns the minimum of free entries of the given event queue.
Definition qf_actq.c:319
QACTIVE_OS_OBJ_TYPE osObject
Port-dependent per-thread object.
Definition qp.h:515
bool QActive_recall(QActive *const me, struct QEQueue *const eq)
Recall a deferred event from a given event queue.
Definition qf_defer.c:77
QACTIVE_EQUEUE_TYPE eQueue
Port-dependent event-queue type (often QEQueue)
Definition qp.h:519
void QActive_publish_(QEvt const *const e, void const *const sender, uint_fast8_t const qsId)
Publish event to all subscribers of a given signal e->sig
Definition qf_ps.c:65
void QActive_stop(QActive *const me)
Stops execution of an active object and removes it from the framework's supervision.
void QActive_register_(QActive *const me)
Register this active object to be managed by the framework.
Definition qf_qact.c:73
uint8_t prio
QF-priority [1..QF_MAX_ACTIVE] of this AO.
Definition qp.h:507
void QActive_subscribe(QActive const *const me, enum_t const sig)
Subscribes for delivery of signal sig to the active object.
Definition qf_ps.c:159
void QActive_start(QActive *const me, QPrioSpec const prioSpec, QEvtPtr *const qSto, uint_fast16_t const qLen, void *const stkSto, uint_fast16_t const stkSize, void const *const par)
Starts execution of an active object and registers the object with the framework.
Definition qv.c:216
uint_fast16_t QActive_flushDeferred(QActive const *const me, struct QEQueue *const eq, uint_fast16_t const num)
Flush the specified number of events from the deferred queue eq
Definition qf_defer.c:131
void QActive_unsubscribeAll(QActive const *const me)
Unsubscribes from the delivery of all signals to the active object.
Definition qf_ps.c:217
void QActive_psInit(QSubscrList *const subscrSto, enum_t const maxSignal)
Publish event to all subscribers of a given signal e->sig
uint8_t pthre
Preemption-threshold [1..QF_MAX_ACTIVE] of this AO.
Definition qp.h:508
void QActive_evtLoop_(QActive *const me)
Event loop thread routine for executing an active object act (defined some in QP ports)
Abstract State Machine class (state machine interface)
Definition qp.h:179
struct QAsmVtable const * vptr
Virtual pointer inherited by all QAsm subclasses (see also SAS_QP_OO)
Definition qp.h:180
union QAsmAttr state
Current state (pointer to the current state-handler function)
Definition qp.h:181
union QAsmAttr temp
Temporary storage for target/act-table etc.
Definition qp.h:182
static void QAsm_ctor(QAsm *const me)
Constructor of the QAsm base class.
Definition qp.h:216
Virtual table for the QAsm class.
Definition qp.h:222
void(* init)(QAsm *const me, void const *const e, uint_fast8_t const qsId)
Virtual function to take the top-most initial transition in the state machine.
Definition qp.h:223
bool(* isIn)(QAsm *const me, QStateHandler const stateHndl)
Virtual function to check whether the state machine is in a given state.
Definition qp.h:227
QStateHandler(* getStateHandler)(QAsm *const me)
Virtual function to get the current state handler of the state machine.
Definition qp.h:229
void(* dispatch)(QAsm *const me, QEvt const *const e, uint_fast8_t const qsId)
Virtual function to dispatch an event to the state machine.
Definition qp.h:225
Native QF Event Queue.
Definition qequeue.h:48
Event class.
Definition qp.h:112
QSignal sig
Signal of the event (see Event Signal)
Definition qp.h:113
static QEvt * QEvt_init(QEvt *const me, uint8_t const dummy)
Event without parameters initialization.
Definition qp.h:129
uint8_t volatile refCtr_
Event reference counter.
Definition qp.h:115
static void QEvt_ctor(QEvt *const me, enum_t const sig)
Definition qp.h:120
uint8_t poolNum_
Event pool number of this event.
Definition qp.h:114
Hierarchical State Machine class (QHsm-style state machine implementation strategy)
Definition qp.h:252
QAsm super
Definition qp.h:253
static QStateHandler QHsm_state(QHsm const *const me)
Obtain the current active state from a HSM (read only)
Definition qp.h:287
Active object class (based on QMsm implementation strategy)
Definition qp.h:610
QActive super
Definition qp.h:611
State object for the QMsm class (QM State Machine)
Definition qp.h:151
struct QMState const * superstate
Definition qp.h:152
QActionHandler const entryAction
Definition qp.h:154
QActionHandler const initAction
Definition qp.h:156
QActionHandler const exitAction
Definition qp.h:155
QStateHandler const stateHandler
Definition qp.h:153
Transition-Action Table for the QMsm State Machine.
Definition qp.h:159
QActionHandler const act[1]
Definition qp.h:161
QMState const * target
Definition qp.h:160
Hierarchical State Machine class (QMsm-style state machine implementation strategy)
Definition qp.h:312
QAsm super
Definition qp.h:313
void QMsm_init_(QAsm *const me, void const *const e, uint_fast8_t const qsId)
Implementation of the top-most initial transition in QMsm.
Definition qep_msm.c:156
bool QMsm_isIn_(QAsm *const me, QStateHandler const stateHndl)
Tests if a given state is part of the current active state configuration.
Definition qep_msm.c:436
QStateHandler QMsm_getStateHandler_(QAsm *const me)
Implementation of getting the state handler in a QMsm subclass.
Definition qep_msm.c:460
static QMState const * QMsm_stateObj(QMsm const *const me)
Obtain the current state from a MSM (read only)
Definition qp.h:343
void QMsm_dispatch_(QAsm *const me, QEvt const *const e, uint_fast8_t const qsId)
Implementation of dispatching events to a QMsm.
Definition qep_msm.c:200
void QMsm_ctor(QMsm *const me, QStateHandler const initial)
Constructor of QMsm.
Set of Active Objects of up to QF_MAX_ACTIVE elements.
Definition qp.h:407
static uint_fast8_t QPSet_findMax(QPSet const *const me)
Find the maximum element in the set–returns zero if the set is empty.
Definition qp.h:485
static bool QPSet_notEmpty(QPSet const *const me)
Find out whether the priority-set is NOT empty.
Definition qp.h:431
static bool QPSet_hasElement(QPSet const *const me, uint_fast8_t const n)
Find out whether the priority-set has element n
Definition qp.h:440
static void QPSet_setEmpty(QPSet *const me)
Make the priority set empty.
Definition qp.h:414
static void QPSet_insert(QPSet *const me, uint_fast8_t const n)
Insert element n into the priority-set (n = 1..QF_MAX_ACTIVE)
Definition qp.h:453
QPSetBits bits[((QF_MAX_ACTIVE+(8U *sizeof(QPSetBits))) - 1U)/(8U *sizeof(QPSetBits))]
Bitmask with a bit for each element.
Definition qp.h:410
static void QPSet_remove(QPSet *const me, uint_fast8_t const n)
Remove element n from the priority-set (n = 1..QF_MAX_ACTIVE)
Definition qp.h:469
static bool QPSet_isEmpty(QPSet const *const me)
Find out whether the priority-set is empty.
Definition qp.h:422
Subscriber List (for publish-subscribe)
Definition qp.h:496
QPSet set
The set of AOs that subscribed to a given event signal.
Definition qp.h:497
"Ticker" Active Object class
Definition qp.h:683
QActive super
Definition qp.h:684
Time Event class.
Definition qp.h:621
void QTimeEvt_ctorX(QTimeEvt *const me, QActive *const act, enum_t const sig, uint_fast8_t const tickRate)
The "extended" constructor to initialize a Time Event.
struct QTimeEvt *volatile next
Link to the next time event in the list.
Definition qp.h:624
QTimeEvtCtr volatile ctr
Down-counter of the time event.
Definition qp.h:626
bool QTimeEvt_noActive(uint_fast8_t const tickRate)
Check if any time events are active at a given clock tick rate.
Definition qf_time.c:370
void QTimeEvt_tick1_(uint_fast8_t const tickRate, void const *const sender)
Processes one clock tick for QUTest.
void QTimeEvt_armX(QTimeEvt *const me, uint32_t const nTicks, uint32_t const interval)
Arm a time event (extended version for one shot or periodic time event)
Definition qf_time.c:72
void QTimeEvt_tick_(uint_fast8_t const tickRate, void const *const sender)
Processes all armed time events at every clock tick.
Definition qf_time.c:282
QTimeEvt * QTimeEvt_expire_(QTimeEvt *const me, QTimeEvt *const prev_link, QActive const *const act, uint_fast8_t const tickRate)
Definition qf_time.c:391
QTimeEvtCtr interval
Interval for periodic time event (zero for one-shot time event)
Definition qp.h:627
QTimeEvtCtr QTimeEvt_currCtr(QTimeEvt const *const me)
Get the current value of the down-counter of a time event.
Definition qf_time.c:259
bool QTimeEvt_rearm(QTimeEvt *const me, uint32_t const nTicks)
Rearm a time event.
Definition qf_time.c:177
void QTimeEvt_init(void)
Definition qf_time.c:270
bool QTimeEvt_wasDisarmed(QTimeEvt *const me)
Check the "was disarmed" status of a time event.
Definition qf_time.c:245
bool QTimeEvt_disarm(QTimeEvt *const me)
Disarm a time event.
Definition qf_time.c:133
uint8_t flags
Definition qp.h:629
QEvt super
Definition qp.h:622
void * act
Active object that receives the time events.
Definition qp.h:625
uint8_t tickRate
Definition qp.h:628
eXtended (blocking) thread of the QXK preemptive kernel
Definition qxk.h:86
Attribute of for the QAsm class (Abstract State Machine)
Definition qp.h:164
uintptr_t uint
Definition qp.h:170
QMTranActTable const * tatbl
Definition qp.h:168
QXThreadHandler thr
Definition qp.h:167
QStateHandler fun
Definition qp.h:165
struct QMState const * obj
Definition qp.h:169
QActionHandler act
Definition qp.h:166