QP/C  8.0.3
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.3"
34#define QP_VERSION 803U
35// <VER>=803 <DATE>=250407
36#define QP_RELEASE 0x6ABEE96CU
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};
171
172#define Q_STATE_CAST(handler_) ((QStateHandler)(handler_))
173#define Q_ACTION_CAST(action_) ((QActionHandler)(action_))
174#define Q_ACTION_NULL ((QActionHandler)0)
175
176//============================================================================
177//! @class QAsm
178typedef struct {
179 struct QAsmVtable const * vptr; //!< @protected @memberof QAsm
180 union QAsmAttr state; //!< @protected @memberof QAsm
181 union QAsmAttr temp; //!< @protected @memberof QAsm
182} QAsm;
183
184// All possible values returned from state/action handlers
185// NOTE: The ordering is important for algorithmic correctness.
186#define Q_RET_SUPER ((QState)0U)
187#define Q_RET_UNHANDLED ((QState)1U)
188
189// handled and do not need to "bubble up"
190#define Q_RET_HANDLED ((QState)2U)
191#define Q_RET_IGNORED ((QState)3U)
192
193// entry/exit
194#define Q_RET_ENTRY ((QState)4U)
195#define Q_RET_EXIT ((QState)5U)
196
197// no side effects
198#define Q_RET_NULL ((QState)6U)
199
200// transitions need to execute transition-action table in ::QMsm
201#define Q_RET_TRAN ((QState)7U)
202#define Q_RET_TRAN_INIT ((QState)8U)
203
204// transitions that additionally clobber me->state
205#define Q_RET_TRAN_HIST ((QState)9U)
206
207// Reserved signals by the QP-framework.
208#define Q_EMPTY_SIG ((QSignal)0U)
209#define Q_ENTRY_SIG ((QSignal)1U)
210#define Q_EXIT_SIG ((QSignal)2U)
211#define Q_INIT_SIG ((QSignal)3U)
212#define Q_USER_SIG ((enum_t)4)
213
214//! @protected @memberof QAsm
215static inline void QAsm_ctor(QAsm * const me) {
216 me->vptr = (struct QAsmVtable *)0;
217 me->state.fun = (QStateHandler)0;
218 me->temp.fun = (QStateHandler)0;
219}
220
222 void (*init)(QAsm * const me, void const * const e,
223 uint_fast8_t const qsId);
224 void (*dispatch)(QAsm * const me, QEvt const * const e,
225 uint_fast8_t const qsId);
226 bool (*isIn)(QAsm * const me, QStateHandler const stateHndl);
227#ifdef Q_SPY
229#endif // Q_SPY
230};
231
232#ifdef Q_SPY
233 #define QASM_INIT(me_, par_, qsId_) \
234 (*((QAsm *)(me_))->vptr->init)((QAsm *)(me_), (par_), (qsId_))
235 #define QASM_DISPATCH(me_, e_, qsId_) \
236 (*((QAsm *)(me_))->vptr->dispatch)((QAsm *)(me_), (e_), (qsId_))
237 #define QASM_IS_IN(me_, stateHndl_) \
238 (*((QAsm *)(me_))->vptr->isIn)((QAsm *)(me_), (stateHndl_))
239#else
240 #define QASM_INIT(me_, par_, dummy) \
241 (*((QAsm *)(me_))->vptr->init)((QAsm *)(me_), (par_), 0U)
242 #define QASM_DISPATCH(me_, e_, dummy) \
243 (*((QAsm *)(me_))->vptr->dispatch)((QAsm *)(me_), (e_), 0U)
244#endif // ndef Q_SPY
245
246#define Q_ASM_UPCAST(ptr_) ((QAsm *)(ptr_))
247
248//============================================================================
249//! @class QHsm
250//! @extends QAsm
251typedef struct {
252 QAsm super; //!< @protected @memberof QHsm
253} QHsm;
254
255//! @protected @memberof QHsm
256void QHsm_ctor(QHsm * const me,
257 QStateHandler const initial);
258
259//! @private @memberof QHsm
260void QHsm_init_(
261 QAsm * const me,
262 void const * const e,
263 uint_fast8_t const qsId);
264
265//! @private @memberof QHsm
266void QHsm_dispatch_(
267 QAsm * const me,
268 QEvt const * const e,
269 uint_fast8_t const qsId);
270
271//! @private @memberof QHsm
272bool QHsm_isIn_(
273 QAsm * const me,
274 QStateHandler const stateHndl);
275
276#ifdef Q_SPY
277//! @private @memberof QHsm
278QStateHandler QHsm_getStateHandler_(QAsm * const me);
279#endif // def Q_SPY
280
281//! @protected @memberof QHsm
282QState QHsm_top(QHsm const * const me,
283 QEvt const * const e);
284
285//! @public @memberof QHsm
286static inline QStateHandler QHsm_state(QHsm const * const me) {
287 return me->super.state.fun;
288}
289
290//! @public @memberof QHsm
291QStateHandler QHsm_childState(QHsm * const me,
292 QStateHandler const parentHndl);
293
294#define Q_HSM_UPCAST(ptr_) ((QHsm *)(ptr_))
295
296#define Q_TRAN(target_) \
297 ((Q_ASM_UPCAST(me))->temp.fun = Q_STATE_CAST(target_), \
298 (QState)Q_RET_TRAN)
299#define Q_TRAN_HIST(hist_) \
300 ((Q_ASM_UPCAST(me))->temp.fun = (hist_), \
301 (QState)Q_RET_TRAN_HIST)
302#define Q_SUPER(super_) \
303 ((Q_ASM_UPCAST(me))->temp.fun = Q_STATE_CAST(super_), \
304 (QState)Q_RET_SUPER)
305#define Q_HANDLED() ((QState)Q_RET_HANDLED)
306#define Q_UNHANDLED() ((QState)Q_RET_UNHANDLED)
307
308//============================================================================
309//! @class QMsm
310//! @extends QAsm
311typedef struct {
312 QAsm super; //!< @protected @memberof QMsm
313} QMsm;
314
315//! @protected @memberof QMsm
316void QMsm_ctor(QMsm * const me,
317 QStateHandler const initial);
318
319//! @private @memberof QMsm
320void QMsm_init_(
321 QAsm * const me,
322 void const * const e,
323 uint_fast8_t const qsId);
324
325//! @private @memberof QMsm
326void QMsm_dispatch_(
327 QAsm * const me,
328 QEvt const * const e,
329 uint_fast8_t const qsId);
330
331//! @private @memberof QMsm
332bool QMsm_isIn_(
333 QAsm * const me,
334 QStateHandler const stateHndl);
335
336#ifdef Q_SPY
337//! @public @memberof QMsm
339#endif // def Q_SPY
340
341//! @public @memberof QMsm
342static inline QMState const * QMsm_stateObj(QMsm const * const me) {
343 return me->super.state.obj;
344}
345
346//! @public @memberof QMsm
347QMState const * QMsm_childStateObj(QMsm const * const me,
348 QMState const * const parent);
349//============================================================================
350// QEP-macros
351
352#define Q_MSM_UPCAST(ptr_) ((QMsm *)(ptr_))
353#ifdef Q_SPY
354 #define QM_ENTRY(state_) \
355 ((Q_ASM_UPCAST(me))->temp.obj = (state_), (QState)Q_RET_ENTRY)
356 #define QM_EXIT(state_) \
357 ((Q_ASM_UPCAST(me))->temp.obj = (state_), (QState)Q_RET_EXIT)
358#else
359 #define QM_ENTRY(dummy) ((QState)Q_RET_ENTRY)
360 #define QM_EXIT(dummy) ((QState)Q_RET_EXIT)
361#endif // ndef Q_SPY
362
363#define QM_TRAN(tatbl_) ((Q_ASM_UPCAST(me))->temp.tatbl \
364 = (struct QMTranActTable const *)(tatbl_), (QState)Q_RET_TRAN)
365
366#define QM_TRAN_INIT(tatbl_) ((Q_ASM_UPCAST(me))->temp.tatbl \
367 = (struct QMTranActTable const *)(tatbl_), (QState)Q_RET_TRAN_INIT)
368
369#define QM_TRAN_HIST(history_, tatbl_) \
370 ((((Q_ASM_UPCAST(me))->state.obj = (history_)), \
371 ((Q_ASM_UPCAST(me))->temp.tatbl = \
372 (struct QMTranActTable const *)(tatbl_))), (QState)Q_RET_TRAN_HIST)
373
374#define QM_HANDLED() ((QState)Q_RET_HANDLED)
375#define QM_UNHANDLED() ((QState)Q_RET_UNHANDLED)
376#define QM_SUPER() ((QState)Q_RET_SUPER)
377#define QM_STATE_NULL ((QMState *)0)
378
379//============================================================================
380// QF (active object framework) types
381
382typedef uint16_t QPrioSpec;
383
384#if (QF_TIMEEVT_CTR_SIZE == 1U)
385 typedef uint8_t QTimeEvtCtr;
386#elif (QF_TIMEEVT_CTR_SIZE == 2U)
387 typedef uint16_t QTimeEvtCtr;
388#elif (QF_TIMEEVT_CTR_SIZE == 4U)
389 typedef uint32_t QTimeEvtCtr;
390#endif // (QF_TIMEEVT_CTR_SIZE == 4U)
391
392#if (QF_MAX_ACTIVE <= 8U)
393 typedef uint8_t QPSetBits;
394#elif (8U < QF_MAX_ACTIVE) && (QF_MAX_ACTIVE <= 16U)
395 typedef uint16_t QPSetBits;
396#elif (16U < QF_MAX_ACTIVE)
397 typedef uint32_t QPSetBits;
398#endif // (16U < QF_MAX_ACTIVE)
399
400#ifndef QF_LOG2
401 uint_fast8_t QF_LOG2(QPSetBits const bitmask);
402#endif // ndef QF_LOG2
403
404//============================================================================
405//! @class QPSet
406typedef struct {
407 //! @private @memberof QPSet
408 QPSetBits bits[((QF_MAX_ACTIVE + (8U*sizeof(QPSetBits))) - 1U)
409 / (8U*sizeof(QPSetBits))];
410} QPSet;
411
412//! @public @memberof QPSet
413static inline void QPSet_setEmpty(QPSet * const me) {
414 me->bits[0] = 0U;
415#if (QF_MAX_ACTIVE > 32)
416 me->bits[1] = 0U;
417#endif
418}
419
420//! @public @memberof QPSet
421static inline bool QPSet_isEmpty(QPSet const * const me) {
422#if (QF_MAX_ACTIVE <= 32U)
423 return (me->bits[0] == 0U);
424#else
425 return (me->bits[0] == 0U) ? (me->bits[1] == 0U) : false;
426#endif
427}
428
429//! @public @memberof QPSet
430static inline bool QPSet_notEmpty(QPSet const * const me) {
431#if (QF_MAX_ACTIVE <= 32U)
432 return (me->bits[0] != 0U);
433#else
434 return (me->bits[0] != 0U) ? true : (me->bits[1] != 0U);
435#endif
436}
437
438//! @public @memberof QPSet
439static inline bool QPSet_hasElement(QPSet const * const me,
440 uint_fast8_t const n)
441{
442#if (QF_MAX_ACTIVE <= 32U)
443 return (me->bits[0] & ((QPSetBits)1U << (n - 1U))) != 0U;
444#else
445 return (n <= 32U)
446 ? ((me->bits[0] & ((QPSetBits)1U << (n - 1U))) != 0U)
447 : ((me->bits[1] & ((QPSetBits)1U << (n - 33U))) != 0U);
448#endif
449}
450
451//! @public @memberof QPSet
452static inline void QPSet_insert(QPSet * const me,
453 uint_fast8_t const n)
454{
455#if (QF_MAX_ACTIVE <= 32U)
456 me->bits[0] = (me->bits[0] | ((QPSetBits)1U << (n - 1U)));
457#else
458 if (n <= 32U) {
459 me->bits[0] = (me->bits[0] | ((QPSetBits)1U << (n - 1U)));
460 }
461 else {
462 me->bits[1] = (me->bits[1] | ((QPSetBits)1U << (n - 33U)));
463 }
464#endif
465}
466
467//! @public @memberof QPSet
468static inline void QPSet_remove(QPSet * const me,
469 uint_fast8_t const n)
470{
471#if (QF_MAX_ACTIVE <= 32U)
472 me->bits[0] = (me->bits[0] & (QPSetBits)(~((QPSetBits)1U << (n - 1U))));
473#else
474 if (n <= 32U) {
475 (me->bits[0] = (me->bits[0] & ~((QPSetBits)1U << (n - 1U))));
476 }
477 else {
478 (me->bits[1] = (me->bits[1] & ~((QPSetBits)1U << (n - 33U))));
479 }
480#endif
481}
482
483//! @public @memberof QPSet
484static inline uint_fast8_t QPSet_findMax(QPSet const * const me) {
485#if (QF_MAX_ACTIVE <= 32U)
486 return QF_LOG2(me->bits[0]);
487#else
488 return (me->bits[1] != 0U)
489 ? (QF_LOG2(me->bits[1]) + 32U)
490 : (QF_LOG2(me->bits[0]));
491#endif
492}
493
494//! @struct QSubscrList
495typedef struct {
496 QPSet set; //!< @private @memberof QSubscrList
498
499struct QEQueue; // forward declaration
500
501//============================================================================
502//! @class QActive
503//! @extends QAsm
504typedef struct QActive {
505 QAsm super; //!< @protected @memberof QActive
506 uint8_t prio; //!< @protected @memberof QActive
507 uint8_t pthre; //!< @protected @memberof QActive
508
509#ifdef QACTIVE_THREAD_TYPE
510 QACTIVE_THREAD_TYPE thread; //!< @protected @memberof QActive
511#endif // def QACTIVE_THREAD_TYPE
512
513#ifdef QACTIVE_OS_OBJ_TYPE
514 QACTIVE_OS_OBJ_TYPE osObject; //!< @protected @memberof QActive
515#endif // def QACTIVE_OS_OBJ_TYPE
516
517#ifdef QACTIVE_EQUEUE_TYPE
518 QACTIVE_EQUEUE_TYPE eQueue; //!< @protected @memberof QActive
519#endif // def QACTIVE_EQUEUE_TYPE
520} QActive;
521
522//! @static @private @memberof QActive
524
525//! @static @private @memberof QActive
527
528//! @static @private @memberof QActive
530
531//! @protected @memberof QActive
532void QActive_ctor(QActive * const me,
533 QStateHandler const initial);
534
535//! @public @memberof QActive
536void QActive_setAttr(QActive * const me,
537 uint32_t attr1,
538 void const * attr2);
539
540//! @public @memberof QActive
541void QActive_start(QActive * const me,
542 QPrioSpec const prioSpec,
543 QEvtPtr * const qSto,
544 uint_fast16_t const qLen,
545 void * const stkSto,
546 uint_fast16_t const stkSize,
547 void const * const par);
548
549#ifdef QACTIVE_CAN_STOP
550//! @protected @memberof QActive
551void QActive_stop(QActive * const me);
552#endif // def QACTIVE_CAN_STOP
553
554//! @private @memberof QActive
555void QActive_register_(QActive * const me);
556
557//! @private @memberof QActive
558void QActive_unregister_(QActive * const me);
559
560//! @private @memberof QActive
561bool QActive_post_(QActive * const me,
562 QEvt const * const e,
563 uint_fast16_t const margin,
564 void const * const sender);
565
566//! @private @memberof QActive
567void QActive_postLIFO_(QActive * const me,
568 QEvt const * const e);
569
570//! @private @memberof QActive
571QEvt const * QActive_get_(QActive * const me);
572
573//! @static @public @memberof QActive
575 QSubscrList * const subscrSto,
576 enum_t const maxSignal);
577
578//! @static @private @memberof QActive
580 QEvt const * const e,
581 void const * const sender,
582 uint_fast8_t const qsId);
583
584//! @static @public @memberof QActive
585uint_fast16_t QActive_getQueueMin(uint_fast8_t const prio);
586
587//! @protected @memberof QActive
588void QActive_subscribe(QActive const * const me,
589 enum_t const sig);
590
591//! @protected @memberof QActive
592void QActive_unsubscribe(QActive const * const me,
593 enum_t const sig);
594
595//! @protected @memberof QActive
596void QActive_unsubscribeAll(QActive const * const me);
597
598//! @protected @memberof QActive
599bool QActive_defer(QActive const * const me,
600 struct QEQueue * const eq,
601 QEvt const * const e);
602
603//! @protected @memberof QActive
604bool QActive_recall(QActive * const me,
605 struct QEQueue * const eq);
606
607//! @protected @memberof QActive
608uint_fast16_t QActive_flushDeferred(QActive const * const me,
609 struct QEQueue * const eq,
610 uint_fast16_t const num);
611
612//! @private @memberof QActive
613void QActive_evtLoop_(QActive * const me);
614
615//============================================================================
616//! @class QMActive
617//! @extends QActive
618typedef struct {
619 QActive super; //!< @protected @memberof QMActive
620} QMActive;
621
622//! @protected @memberof QMActive
623void QMActive_ctor(QMActive * const me,
624 QStateHandler const initial);
625
626//============================================================================
627//! @class QTimeEvt
628//! @extends QEvt
629typedef struct QTimeEvt {
630 QEvt super; //!< @protected @memberof QTimeEvt
631
632 struct QTimeEvt * volatile next; //!< @private @memberof QTimeEvt
633 void * act; //!< @private @memberof QTimeEvt
634 QTimeEvtCtr volatile ctr; //!< @private @memberof QTimeEvt
635 QTimeEvtCtr interval; //!< @private @memberof QTimeEvt
636 uint8_t tickRate; //!< @private @memberof QTimeEvt
637 uint8_t flags; //!< @private @memberof QTimeEvt
638} QTimeEvt;
639
640//! @public @memberof QTimeEvt
641void QTimeEvt_ctorX(QTimeEvt * const me,
642 QActive * const act,
643 enum_t const sig,
644 uint_fast8_t const tickRate);
645
646//! @public @memberof QTimeEvt
647void QTimeEvt_armX(QTimeEvt * const me,
648 uint32_t const nTicks,
649 uint32_t const interval);
650
651//! @public @memberof QTimeEvt
652bool QTimeEvt_disarm(QTimeEvt * const me);
653
654//! @public @memberof QTimeEvt
655bool QTimeEvt_rearm(QTimeEvt * const me,
656 uint32_t const nTicks);
657
658//! @public @memberof QTimeEvt
659bool QTimeEvt_wasDisarmed(QTimeEvt * const me);
660
661//! @public @memberof QTimeEvt
662QTimeEvtCtr QTimeEvt_currCtr(QTimeEvt const * const me);
663
664//! @static @private @memberof QTimeEvt
665void QTimeEvt_init(void);
666
667//! @static @private @memberof QTimeEvt
668void QTimeEvt_tick_(
669 uint_fast8_t const tickRate,
670 void const * const sender);
671
672//! @private @memberof QTimeEvt
674 QTimeEvt * const prev_link,
675 QActive const * const act,
676 uint_fast8_t const tickRate);
677
678#ifdef Q_UTEST
679 //! @static @private @memberof QTimeEvt
681 uint_fast8_t const tickRate,
682 void const * const sender);
683#endif // def Q_UTEST
684
685//! @static @public @memberof QTimeEvt
686bool QTimeEvt_noActive(uint_fast8_t const tickRate);
687
688//! @static @private @memberof QTimeEvt
690
691//============================================================================
692//! @class QTicker
693//! @extends QActive
694typedef struct {
695 QActive super; //!< @protected @memberof QTicker
696} QTicker;
697
698//! @public @memberof QTicker
699void QTicker_ctor(QTicker * const me,
700 uint_fast8_t const tickRate);
701
702//! @private @memberof QTicker
703void QTicker_init_(
704 QAsm * const me,
705 void const * const par,
706 uint_fast8_t const qsId);
707
708//! @private @memberof QTicker
709void QTicker_dispatch_(
710 QAsm * const me,
711 QEvt const * const e,
712 uint_fast8_t const qsId);
713
714//! @private @memberof QTicker
715void QTicker_trig_(
716 QActive * const me,
717 void const * const sender);
718
719//============================================================================
720// QF base facilities
721
722//! @static @public @memberof QF
723void QF_init(void);
724
725//! @static @public @memberof QF
726void QF_stop(void);
727
728//! @static @public @memberof QF
729int_t QF_run(void);
730
731//! @static @public @memberof QF
732void QF_onStartup(void);
733
734//! @static @public @memberof QF
735void QF_onCleanup(void);
736
737#ifdef QF_ON_CONTEXT_SW
738 //! @static @public @memberof QF
740 QActive * prev,
741 QActive * next);
742#endif // def QF_ON_CONTEXT_SW
743
744#define Q_PRIO(prio_, pthre_) ((QPrioSpec)((prio_) | ((pthre_) << 8U)))
745#define QF_NO_MARGIN ((uint_fast16_t)0xFFFFU)
746
747//============================================================================
748// QF dynamic memory facilities
749
750//! @static @public @memberof QF
752 void * const poolSto,
753 uint_fast32_t const poolSize,
754 uint_fast16_t const evtSize);
755
756//! @static @public @memberof QF
757uint_fast16_t QF_poolGetMaxBlockSize(void);
758
759//! @static @public @memberof QF
760uint_fast16_t QF_getPoolMin(uint_fast8_t const poolNum);
761
762//! @static @private @memberof QF
763QEvt * QF_newX_(
764 uint_fast16_t const evtSize,
765 uint_fast16_t const margin,
766 enum_t const sig);
767
768//! @static @public @memberof QF
769void QF_gc(QEvt const * const e);
770
771//! @static @private @memberof QF
772QEvt const * QF_newRef_(
773 QEvt const * const e,
774 void const * const evtRef);
775
776//! @static @private @memberof QF
777void QF_deleteRef_(void const * const evtRef);
778
779//! @static @public @memberof QF
780void QF_gcFromISR(QEvt const * const e);
781
782#ifdef QEVT_PAR_INIT
783 #define Q_NEW(evtT_, sig_, ...) \
784 (evtT_##_init((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \
785 QF_NO_MARGIN, (sig_)), __VA_ARGS__))
786 #define Q_NEW_X(evtT_, margin_, sig_, ...) \
787 (evtT_##_init((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \
788 (margin_), (sig_)), __VA_ARGS__))
789#else
790 #define Q_NEW(evtT_, sig_) \
791 ((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \
792 QF_NO_MARGIN, (enum_t)(sig_)))
793 #define Q_NEW_X(evtT_, margin_, sig_) \
794 ((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \
795 (margin_), (enum_t)(sig_)))
796#endif // QEVT_PAR_INIT
797
798#define Q_NEW_REF(evtRef_, evtT_) \
799 ((evtRef_) = (evtT_ const *)QF_newRef_(e, (evtRef_)))
800#define Q_DELETE_REF(evtRef_) do { \
801 QF_deleteRef_((evtRef_)); \
802 (evtRef_) = (void *)0; \
803} while (false)
804
805#ifdef Q_SPY
806 #define QACTIVE_POST(me_, e_, sender_) \
807 ((void)QActive_post_((me_), (e_), QF_NO_MARGIN, (sender_)))
808 #define QACTIVE_POST_X(me_, e_, margin_, sender_) \
809 (QActive_post_((me_), (e_), (margin_), (sender_)))
810 #define QACTIVE_PUBLISH(e_, sender_) \
811 (QActive_publish_((e_), (void const *)(sender_), (sender_)->prio))
812 #define QTIMEEVT_TICK_X(tickRate_, sender_) (QTimeEvt_tick_((tickRate_), (sender_)))
813 #define QTICKER_TRIG(ticker_, sender_) (QTicker_trig_((ticker_), (sender_)))
814#else
815 #define QACTIVE_POST(me_, e_, dummy) \
816 ((void)QActive_post_((me_), (e_), QF_NO_MARGIN, (void *)0))
817 #define QACTIVE_POST_X(me_, e_, margin_, dummy) \
818 (QActive_post_((me_), (e_), (margin_), (void *)0))
819 #define QACTIVE_PUBLISH(e_, dummy) (QActive_publish_((e_), (void *)0, 0U))
820 #define QTIMEEVT_TICK_X(tickRate_, dummy) (QTimeEvt_tick_((tickRate_), (void *)0))
821 #define QTICKER_TRIG(ticker_, sender_) (QTicker_trig_((ticker_), (void *)0))
822#endif // ndef Q_SPY
823
824#define QACTIVE_POST_LIFO(me_, e_) (QActive_postLIFO_((me_), (e_)))
825#define QTIMEEVT_TICK(sender_) QTIMEEVT_TICK_X(0U, (sender_))
826
827#ifndef QF_CRIT_EXIT_NOP
828 #define QF_CRIT_EXIT_NOP() ((void)0)
829#endif // ndef QF_CRIT_EXIT_NOP
830
831//============================================================================
832// memory protection facilities
833
834#ifdef QF_MEM_ISOLATE
835 #error Memory isolation not supported in this QP edition, need SafeQP
836#endif // def QF_MEM_ISOLATE
837
838#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:182
uint_fast16_t QF_poolGetMaxBlockSize(void)
Obtain the block size of any registered event pools.
Definition qf_dyn.c:81
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:93
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:109
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:273
QEvt const * QF_newRef_(QEvt const *const e, void const *const evtRef)
Internal QF implementation of creating new event reference.
Definition qf_dyn.c:237
eXtended (blocking) thread of the QXK preemptive kernel
#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:397
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:389
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:382
#define QF_MAX_TICK_RATE
Maximum # clock tick rates in the system (0..15)
Definition qp_config.h:143
#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:504
QSubscrList * QActive_subscrList_
Static (one per-class) pointer to all subscriber AOs for a given event signal.
Definition qp.h:526
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:182
QAsm super
Definition qp.h:505
void QActive_unregister_(QActive *const me)
Un-register the active object from the framework.
Definition qf_qact.c:122
QACTIVE_THREAD_TYPE thread
Port-dependent representation of the thread of the active object.
Definition qp.h:510
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:208
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:130
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)
enum_t QActive_maxPubSignal_
Static (one per-class) maximum published signal (the size of the subscrList_ array)
Definition qp.h:529
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:335
QACTIVE_OS_OBJ_TYPE osObject
Port-dependent per-thread object.
Definition qp.h:514
bool QActive_recall(QActive *const me, struct QEQueue *const eq)
Recall a deferred event from a given event queue.
Definition qf_defer.c:66
QACTIVE_EQUEUE_TYPE eQueue
Port-dependent event-queue type (often QEQueue)
Definition qp.h:518
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:62
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
QActive * QActive_registry_[QF_MAX_ACTIVE+1U]
Static (one per-class) array of registered active objects.
Definition qp.h:523
uint8_t prio
QF-priority [1..QF_MAX_ACTIVE] of this AO.
Definition qp.h:506
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:155
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:213
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:119
void QActive_unsubscribeAll(QActive const *const me)
Unsubscribes from the delivery of all signals to the active object.
Definition qf_ps.c:209
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:507
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:178
struct QAsmVtable const * vptr
Virtual pointer inherited by all QAsm subclasses (see also SAS_QP_OO)
Definition qp.h:179
union QAsmAttr state
Current state (pointer to the current state-handler function)
Definition qp.h:180
union QAsmAttr temp
Temporary storage for target/act-table etc.
Definition qp.h:181
static void QAsm_ctor(QAsm *const me)
Constructor of the QAsm base class.
Definition qp.h:215
Virtual table for the QAsm class.
Definition qp.h:221
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:222
bool(* isIn)(QAsm *const me, QStateHandler const stateHndl)
Virtual function to check whether the state machine is in a given state.
Definition qp.h:226
QStateHandler(* getStateHandler)(QAsm *const me)
Virtual function to get the current state handler of the state machine.
Definition qp.h:228
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:224
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:251
QAsm super
Definition qp.h:252
static QStateHandler QHsm_state(QHsm const *const me)
Obtain the current active state from a HSM (read only)
Definition qp.h:286
Active object class (based on QMsm implementation strategy)
Definition qp.h:618
QActive super
Definition qp.h:619
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:311
QAsm super
Definition qp.h:312
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:158
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:300
QStateHandler QMsm_getStateHandler_(QAsm *const me)
Implementation of getting the state handler in a QMsm subclass.
Definition qep_msm.c:321
static QMState const * QMsm_stateObj(QMsm const *const me)
Obtain the current state from a MSM (read only)
Definition qp.h:342
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:199
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:406
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:484
static bool QPSet_notEmpty(QPSet const *const me)
Find out whether the priority-set is NOT empty.
Definition qp.h:430
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:439
static void QPSet_setEmpty(QPSet *const me)
Make the priority set empty.
Definition qp.h:413
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:452
QPSetBits bits[((QF_MAX_ACTIVE+(8U *sizeof(QPSetBits))) - 1U)/(8U *sizeof(QPSetBits))]
Bitmask with a bit for each element.
Definition qp.h:409
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:468
static bool QPSet_isEmpty(QPSet const *const me)
Find out whether the priority-set is empty.
Definition qp.h:421
Subscriber List (for publish-subscribe)
Definition qp.h:495
QPSet set
The set of AOs that subscribed to a given event signal.
Definition qp.h:496
"Ticker" Active Object class
Definition qp.h:694
QActive super
Definition qp.h:695
Time Event class.
Definition qp.h:629
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:632
QTimeEvtCtr volatile ctr
Down-counter of the time event.
Definition qp.h:634
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:376
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:286
QTimeEvt * QTimeEvt_expire_(QTimeEvt *const me, QTimeEvt *const prev_link, QActive const *const act, uint_fast8_t const tickRate)
Definition qf_time.c:397
QTimeEvtCtr interval
Interval for periodic time event (zero for one-shot time event)
Definition qp.h:635
QTimeEvtCtr QTimeEvt_currCtr(QTimeEvt const *const me)
Get the current value of the down-counter of a time event.
Definition qf_time.c:263
QTimeEvt QTimeEvt_timeEvtHead_[QF_MAX_TICK_RATE]
Static array of heads of linked lists of time events (one for every clock tick rate)
Definition qp.h:689
bool QTimeEvt_rearm(QTimeEvt *const me, uint32_t const nTicks)
Rearm a time event.
Definition qf_time.c:180
void QTimeEvt_init(void)
Definition qf_time.c:274
bool QTimeEvt_wasDisarmed(QTimeEvt *const me)
Check the "was disarmed" status of a time event.
Definition qf_time.c:249
bool QTimeEvt_disarm(QTimeEvt *const me)
Disarm a time event.
Definition qf_time.c:136
uint8_t flags
Definition qp.h:637
QEvt super
Definition qp.h:630
void * act
Active object that receives the time events.
Definition qp.h:633
uint8_t tickRate
Definition qp.h:636
Attribute of for the QAsm class (Abstract State Machine)
Definition qp.h:164
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