39#define QP_VERSION_STR "8.0.0"
40#define QP_VERSION 800U
41#define QP_RELEASE 0x7055936FU
47#define Q_SIGNAL_SIZE 2U
51#define QF_MAX_ACTIVE 32U
54#if (QF_MAX_ACTIVE > 64U)
55#error QF_MAX_ACTIVE exceeds the maximum of 64U;
58#ifndef QF_MAX_TICK_RATE
59#define QF_MAX_TICK_RATE 1U
62#if (QF_MAX_TICK_RATE > 15U)
63#error QF_MAX_TICK_RATE exceeds the maximum of 15U;
67#define QF_MAX_EPOOL 3U
70#if (QF_MAX_EPOOL > 15U)
71#error QF_MAX_EPOOL exceeds the maximum of 15U;
74#ifndef QF_TIMEEVT_CTR_SIZE
75#define QF_TIMEEVT_CTR_SIZE 4U
78#if (QF_TIMEEVT_CTR_SIZE > 4U)
79#error QF_TIMEEVT_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U;
82#ifndef QF_EVENT_SIZ_SIZE
83#define QF_EVENT_SIZ_SIZE 2U
86#if (QF_EVENT_SIZ_SIZE > 4U)
87#error QF_EVENT_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U;
115#if (Q_SIGNAL_SIZE == 1U)
120#if (Q_SIGNAL_SIZE == 2U)
125#if (Q_SIGNAL_SIZE == 4U)
174 && (((me->
evtTag_ ^ rc) & 0x0FU) == 0x0FU);
180 return (uint_fast8_t)(me->
evtTag_ >> 4U);
278 void (*
init)(
QAsm *
const me,
void const *
const e,
279 uint_fast8_t
const qsId);
281 uint_fast8_t
const qsId);
300void QHsm_ctor(
QHsm *
const me,
308 void const *
const e,
309 uint_fast8_t
const qsId);
314 QEvt const *
const e,
315 uint_fast8_t
const qsId);
341int_fast8_t QHsm_tran_(
344 uint_fast8_t
const qsId);
350 QEvt const *
const e);
363void QMsm_ctor(
QMsm *
const me,
371 void const *
const e,
372 uint_fast8_t
const qsId);
379 QEvt const *
const e,
380 uint_fast8_t
const qsId);
402QMState const * QMsm_childStateObj(
QMsm const *
const me,
411 uint_fast8_t
const qsId);
414void QMsm_exitToTranSource_(
418 uint_fast8_t
const qsId);
424 uint_fast8_t
const qsId);
430#define QEVT_INITIALIZER(sig_) { (QSignal)(sig_), 0x01U, 0x0EU }
433#define QEVT_DYNAMIC ((uint8_t)0)
437#define QASM_INIT(me_, par_, qsId_) do { \
438 Q_ASSERT(((QAsm *)(me_))->vptr); \
439 (*((QAsm *)(me_))->vptr->init)((QAsm *)(me_), (par_), (qsId_)); \
445#define QASM_INIT(me_, par_, dummy) do { \
446 Q_ASSERT(((QAsm *)(me_))->vptr); \
447 (*((QAsm *)(me_))->vptr->init)((QAsm *)(me_), (par_), 0); \
453#define QASM_DISPATCH(me_, e_, qsId_) \
454 (*((QAsm *)(me_))->vptr->dispatch)((QAsm *)(me_), (e_), (qsId_))
459#define QASM_DISPATCH(me_, e_, dummy) \
460 (*((QAsm *)(me_))->vptr->dispatch)((QAsm *)(me_), (e_), 0U)
464#define QASM_IS_IN(me_, state_) \
465 (*((QAsm *)(me_))->vptr->isIn)((QAsm *)(me_), (state_))
468#define Q_ASM_UPCAST(ptr_) ((QAsm *)(ptr_))
471#define Q_HSM_UPCAST(ptr_) ((QHsm *)(ptr_))
474#define Q_MSM_UPCAST(ptr_) ((QMsm *)(ptr_))
477#define Q_EMPTY_SIG ((QSignal)0)
480#define Q_ENTRY_SIG ((QSignal)1)
483#define Q_EXIT_SIG ((QSignal)2)
486#define Q_INIT_SIG ((QSignal)3)
489#define Q_USER_SIG ((enum_t)4)
492#define Q_TRAN(target_) \
493 ((Q_ASM_UPCAST(me))->temp.fun = Q_STATE_CAST(target_), \
497#define Q_TRAN_HIST(hist_) \
498 ((Q_ASM_UPCAST(me))->temp.fun = (hist_), \
499 (QState)Q_RET_TRAN_HIST)
502#define Q_SUPER(super_) \
503 ((Q_ASM_UPCAST(me))->temp.fun = Q_STATE_CAST(super_), \
507#define Q_HANDLED() ((QState)Q_RET_HANDLED)
510#define Q_UNHANDLED() ((QState)Q_RET_UNHANDLED)
513#define Q_ACTION_NULL ((QActionHandler)0)
516#define Q_EVT_CAST(class_) ((class_ const *)(e))
519#define Q_STATE_CAST(handler_) ((QStateHandler)(handler_))
522#define Q_ACTION_CAST(action_) ((QActionHandler)(action_))
525#define Q_UNUSED_PAR(par_) ((void)(par_))
528#define Q_DIM(array_) (sizeof(array_) / sizeof((array_)[0U]))
531#define Q_UINT2PTR_CAST(type_, uint_) ((type_ *)(uint_))
535#define QM_ENTRY(state_) \
536 ((Q_ASM_UPCAST(me))->temp.obj = (state_), \
542#define QM_ENTRY(dummy) ((QState)Q_RET_ENTRY)
547#define QM_EXIT(state_) \
548 ((Q_ASM_UPCAST(me))->temp.obj = (state_), \
554#define QM_EXIT(dummy) ((QState)Q_RET_EXIT)
558#define QM_SM_EXIT(state_) \
559 ((Q_ASM_UPCAST(me))->temp.obj = (state_), \
563#define QM_TRAN(tatbl_) ((Q_ASM_UPCAST(me))->temp.tatbl \
564 = (struct QMTranActTable const *)(tatbl_), \
568#define QM_TRAN_INIT(tatbl_) ((Q_ASM_UPCAST(me))->temp.tatbl \
569 = (struct QMTranActTable const *)(tatbl_), \
570 (QState)Q_RET_TRAN_INIT)
573#define QM_TRAN_HIST(history_, tatbl_) \
574 ((((Q_ASM_UPCAST(me))->state.obj = (history_)), \
575 ((Q_ASM_UPCAST(me))->temp.tatbl = \
576 (struct QMTranActTable const *)(tatbl_))), \
577 (QState)Q_RET_TRAN_HIST)
580#define QM_HANDLED() ((QState)Q_RET_HANDLED)
583#define QM_UNHANDLED() ((QState)Q_RET_UNHANDLED)
586#define QM_SUPER() ((QState)Q_RET_SUPER)
589#define QM_STATE_NULL ((QMState *)0)
598#if (QF_TIMEEVT_CTR_SIZE == 1U)
603#if (QF_TIMEEVT_CTR_SIZE == 2U)
608#if (QF_TIMEEVT_CTR_SIZE == 4U)
613#if (QF_MAX_ACTIVE <= 8U)
618#if (8U < QF_MAX_ACTIVE) && (QF_MAX_ACTIVE <= 16U)
623#if (16U < QF_MAX_ACTIVE)
646 #if (QF_MAX_ACTIVE > 32)
653 #if (QF_MAX_ACTIVE <= 32U)
654 return (me->
bits[0] == 0U);
656 return (me->
bits[0] == 0U) ? (me->
bits[1] == 0U) :
false;
662 #if (QF_MAX_ACTIVE <= 32U)
663 return (me->
bits[0] != 0U);
665 return (me->
bits[0] != 0U) ? true : (me->
bits[1] != 0U);
671 uint_fast8_t
const n)
673 #if (QF_MAX_ACTIVE <= 32U)
684 uint_fast8_t
const n)
686 #if (QF_MAX_ACTIVE <= 32U)
700 uint_fast8_t
const n)
702 #if (QF_MAX_ACTIVE <= 32U)
716 #if (QF_MAX_ACTIVE <= 32U)
719 return (me->
bits[1] != 0U)
732 dis->
bits[0] = ~me->bits[0];
733 #if (QF_MAX_ACTIVE > 32U)
734 dis->
bits[1] = ~me->bits[1];
742 QPSet const *
const dis)
744 #if (QF_MAX_ACTIVE <= 32U)
789#ifdef QACTIVE_THREAD_TYPE
794#ifdef QACTIVE_OS_OBJ_TYPE
799#ifdef QACTIVE_EQUEUE_TYPE
840void QActive_start(
QActive *
const me,
843 uint_fast16_t
const qLen,
845 uint_fast16_t
const stkSize,
846 void const *
const par);
850#ifdef QACTIVE_CAN_STOP
858void QActive_register_(
QActive *
const me);
861void QActive_unregister_(
QActive *
const me);
865 QEvt const *
const e,
866 uint_fast16_t
const margin,
867 void const *
const sender);
870void QActive_postLIFO_(
QActive *
const me,
871 QEvt const *
const e);
886void QActive_publish_(
887 QEvt const *
const e,
888 void const *
const sender,
889 uint_fast8_t
const qsId);
894void QActive_subscribe(
QActive const *
const me,
898void QActive_unsubscribe(
QActive const *
const me,
902void QActive_unsubscribeAll(
QActive const *
const me);
907 QEvt const *
const e);
910bool QActive_recall(
QActive *
const me,
914uint_fast16_t QActive_flushDeferred(
QActive const *
const me,
916 uint_fast16_t
const num);
937void QMActive_ctor(
QMActive *
const me,
999 uint32_t
const nTicks,
1007 uint32_t
const nTicks);
1021 void const *
const sender);
1029 void const *
const sender);
1051void QTicker_ctor(
QTicker *
const me,
1052 uint_fast8_t
const tickRate);
1059 void const *
const par,
1060 uint_fast8_t
const qsId);
1063void QTicker_dispatch_(
1065 QEvt const *
const e,
1066 uint_fast8_t
const qsId);
1071 void const *
const sender);
1090uint_fast16_t QF_getQueueMin(uint_fast8_t
const prio);
1101#ifdef QF_ON_CONTEXT_SW
1114 void *
const poolSto,
1115 uint_fast32_t
const poolSize,
1116 uint_fast16_t
const evtSize);
1120uint_fast16_t QF_poolGetMaxBlockSize(
void);
1124uint_fast16_t QF_getPoolMin(uint_fast8_t
const poolNum);
1129 uint_fast16_t
const evtSize,
1130 uint_fast16_t
const margin,
1135void QF_gc(
QEvt const *
const e);
1139QEvt const * QF_newRef_(
1140 QEvt const *
const e,
1141 void const *
const evtRef);
1145void QF_deleteRef_(
void const *
const evtRef);
1155#define QF_NO_MARGIN ((uint_fast16_t)0xFFFFU)
1158#define Q_PRIO(prio_, pthre_) ((QPrioSpec)((prio_) | ((pthre_) << 8U)))
1161#ifndef QEVT_PAR_INIT
1162#define Q_NEW(evtT_, sig_) ((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \
1163 QF_NO_MARGIN, (enum_t)(sig_)))
1168#define Q_NEW(evtT_, sig_, ...) \
1169 (evtT_##_init((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \
1170 QF_NO_MARGIN, (sig_)), __VA_ARGS__))
1174#ifndef QEVT_PAR_INIT
1175#define Q_NEW_X(evtT_, margin_, sig_) \
1176 ((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \
1177 (margin_), (enum_t)(sig_)))
1182#define Q_NEW_X(evtT_, margin_, sig_, ...) \
1183 (evtT_##_init((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \
1184 (margin_), (sig_)), __VA_ARGS__))
1188#define Q_NEW_REF(evtRef_, evtT_) \
1189 ((evtRef_) = (evtT_ const *)QF_newRef_(e, (evtRef_)))
1192#define Q_DELETE_REF(evtRef_) do { \
1193 QF_deleteRef_((evtRef_)); \
1194 (evtRef_) = (void *)0; \
1199#define QACTIVE_POST(me_, e_, sender_) \
1200 ((void)QActive_post_((me_), (e_), QF_NO_MARGIN, (sender_)))
1205#define QACTIVE_POST(me_, e_, dummy) \
1206 ((void)QActive_post_((me_), (e_), QF_NO_MARGIN, (void *)0))
1211#define QACTIVE_POST_X(me_, e_, margin_, sender_) \
1212 (QActive_post_((me_), (e_), (margin_), (sender_)))
1217#define QACTIVE_POST_X(me_, e_, margin_, dummy) \
1218 (QActive_post_((me_), (e_), (margin_), (void *)0))
1222#define QACTIVE_POST_LIFO(me_, e_) \
1223 (QActive_postLIFO_((me_), (e_)))
1227#define QACTIVE_PUBLISH(e_, sender_) \
1228 (QActive_publish_((e_), (void const *)(sender_), (sender_)->prio))
1233#define QACTIVE_PUBLISH(e_, dummy) (QActive_publish_((e_), (void *)0, 0U))
1238#define QTIMEEVT_TICK_X(tickRate_, sender_) (QTimeEvt_tick_((tickRate_), (sender_)))
1243#define QTIMEEVT_TICK_X(tickRate_, dummy) (QTimeEvt_tick_((tickRate_), (void *)0))
1247#define QTIMEEVT_TICK(sender_) QTIMEEVT_TICK_X(0U, (sender_))
1251#define QTICKER_TRIG(ticker_, sender_) (QTicker_trig_((ticker_), (sender_)))
1256#define QTICKER_TRIG(ticker_, sender_) (QTicker_trig_((ticker_), (void *)0))
1260#ifndef QF_CRIT_EXIT_NOP
1261#define QF_CRIT_EXIT_NOP() ((void)0)
1265#define QF_TICK_X(tickRate_, sender_) QTIMEEVT_TICK_X((tickRate_), (sender_))
1268#define QF_TICK(sender_) QTIMEEVT_TICK(sender_)
1271#define QF_PUBLISH(e_, sender_) QACTIVE_PUBLISH((e_), (sender_))
1275#define QF_MEM_SYS() ((void)0)
1280#define QF_MEM_APP() ((void)0)
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_onContextSw(QActive *prev, QActive *next)
QF context switch callback used in built-in kernels (QV/QK/QXK)
void QF_gcFromISR(QEvt const *const e)
eXtended (blocking) thread of the QXK preemptive kernel
@ Q_RET_ENTRY
state entry action executed
@ Q_RET_HANDLED
event handled (internal transition)
@ Q_RET_IGNORED
event silently ignored (bubbled up to top)
@ Q_RET_TRAN_INIT
initial transition in a state
@ Q_RET_TRAN
regular transition
@ Q_RET_UNHANDLED
event unhandled due to guard
@ Q_RET_SUPER
event passed to superstate to handle
@ Q_RET_NULL
return value without any effect
@ Q_RET_TRAN_HIST
transition to history of a given state
@ Q_RET_EXIT
state exit action executed
QEvt const QEvt_reserved_[4]
char const QP_versionStr[16]
the current QP version number string in ROM, based on QP_VERSION_STR
float float32_t
Alias for IEEE 754 32-bit floating point number.
void(* QXThreadHandler)(struct QXThread *const me)
Pointer to an extended-thread handler function.
uint32_t QPSetBits
Bitmask for the internal representation of QPSet elements.
QState(* QStateHandler)(void *const me, QEvt const *const e)
Pointer to a state-handler function.
QEvt const * QEvtPtr
Pointer to const event instances passed around in QP Framework.
enum QStateRet QState
Type returned from state-handler functions.
uint32_t QTimeEvtCtr
Data type to store the block-size defined based on the macro QF_TIMEEVT_CTR_SIZE.
uint_fast8_t QF_LOG2(QPSetBits const bitmask)
Log-base-2 calculation when hardware acceleration is NOT provided (QF_LOG2 not defined)
int int_t
Alias for assertion-ID numbers in QP assertions and return from QF_run()
double float64_t
Alias for IEEE 754 64-bit floating point number.
QState(* QActionHandler)(void *const me)
Pointer to an action-handler function.
uint16_t QSignal
The signal of event QEvt.
uint16_t QPrioSpec
Priority specification for Active Objects in QP.
#define QF_MAX_TICK_RATE
Maximum # clock tick rates in the system (0..15)
#define QF_MAX_ACTIVE
Maximum # Active Objects in the system (1..64)
#define QACTIVE_OS_OBJ_TYPE
QActive "OS-object" type used in various QP/C ports.
#define QACTIVE_EQUEUE_TYPE
QActive event queue type used in various QP/C ports.
#define QACTIVE_THREAD_TYPE
QActive "thread" type used in various QP/C ports.
Active object class (based on the QHsm implementation strategy)
QSubscrList * QActive_subscrList_
Static (one per-class) pointer to all subscriber AOs for a given event signal.
QACTIVE_THREAD_TYPE thread
Port-dependent representation of the thread of the active object.
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)...
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)
QACTIVE_OS_OBJ_TYPE osObject
Port-dependent per-thread object.
QACTIVE_EQUEUE_TYPE eQueue
Port-dependent event-queue type (often QEQueue)
void QActive_stop(QActive *const me)
Stops execution of an active object and removes it from the framework's supervision.
uint8_t prio
QF-priority [1..QF_MAX_ACTIVE] of this AO.
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.
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)
struct QAsmVtable const * vptr
Virtual pointer inherited by all QAsm subclasses (see also Object Orientation)
void QAsm_ctor(QAsm *const me)
Constructor of the QAsm base class.
union QAsmAttr state
Current state (pointer to the current state-handler function)
Virtual table for the QAsm class.
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.
bool(* isIn)(QAsm *const me, QStateHandler const s)
Virtual function to check whether the state machine is in a given state.
QStateHandler(* getStateHandler)(QAsm *const me)
Virtual function to get the current state handler of the state machine.
void(* dispatch)(QAsm *const me, QEvt const *const e, uint_fast8_t const qsId)
Virtual function to dispatch an event to the state machine.
static QEvt * QEvt_init(QEvt *const me, uint8_t dummy)
Event without parameters initialization.
QSignal sig
Signal of the event (see Event Signal)
uint8_t evtTag_
Event "tag" contains pool-ID plus the Duplicate Inverted Storage of the QEvt::refCtr_.
uint8_t volatile refCtr_
Event reference counter.
static uint_fast8_t QEvt_getPoolNum_(QEvt const *const me)
Internal function to get the event pool-number of the given event.
static void QEvt_ctor(QEvt *const me, enum_t const sig)
static bool QEvt_verify_(QEvt const *const me)
Internal function to verify the internal integrity of the event instance (QP FuSa Subsystem)
Hierarchical State Machine class (QHsm-style state machine implementation strategy)
static QStateHandler QHsm_state(QHsm const *const me)
Obtain the current active state from a HSM (read only)
Active object class (based on QMsm implementation strategy)
State object for the QMsm class (QM State Machine)
struct QMState const * superstate
QActionHandler const entryAction
QActionHandler const initAction
QActionHandler const exitAction
QStateHandler const stateHandler
Transition-Action Table for the QMsm State Machine.
QActionHandler const act[1]
Hierarchical State Machine class (QMsm-style state machine implementation strategy)
static QStateHandler QMsm_getStateHandler_(QAsm *const me)
Implementation of getting the state handler in a QMsm subclass.
static QMState const * QMsm_stateObj(QMsm const *const me)
Obtain the current state from a MSM (read only)
Set of Active Objects of up to QF_MAX_ACTIVE elements.
static uint_fast8_t QPSet_findMax(QPSet const *const me)
Find the maximum element in the set–returns zero if the set is empty.
static bool QPSet_notEmpty(QPSet const *const me)
Find out whether the priority-set is NOT empty.
static bool QPSet_verify_(QPSet const *const me, QPSet const *const dis)
Verify the Duplicate Inverse Storage (QP FuSa Subsystem)
static bool QPSet_hasElement(QPSet const *const me, uint_fast8_t const n)
Find out whether the priority-set has element n
static void QPSet_setEmpty(QPSet *const me)
Make the priority set empty.
static void QPSet_insert(QPSet *const me, uint_fast8_t const n)
Insert element n into the priority-set (n = 1..QF_MAX_ACTIVE)
QPSetBits bits[((QF_MAX_ACTIVE+(8U *sizeof(QPSetBits))) - 1U)/(8U *sizeof(QPSetBits))]
Bitmask with a bit for each element.
static void QPSet_remove(QPSet *const me, uint_fast8_t const n)
Remove element n from the priority-set (n = 1..QF_MAX_ACTIVE)
static void QPSet_update_(QPSet const *const me, QPSet *const dis)
Update the Duplicate Inverse Storage of QPSet (QP FuSa Subsystem)
static bool QPSet_isEmpty(QPSet const *const me)
Find out whether the priority-set is empty.
Subscriber List (for publish-subscribe)
QPSet set_dis
Duplicate inverse storage for the AO set.
QPSet set
The set of AOs that subscribed to a given event signal.
"Ticker" Active Object class
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.
QTimeEvtCtr volatile ctr
Down-counter of the time event.
bool QTimeEvt_noActive(uint_fast8_t const tickRate)
Check if any time events are active at a given clock tick rate.
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)
void QTimeEvt_tick_(uint_fast8_t const tickRate, void const *const sender)
Processes all armed time events at every clock tick.
uintptr_t QTimeEvt_timeEvtHead_dis_[QF_MAX_TICK_RATE]
QTimeEvtCtr interval
Interval for periodic time event (zero for one-shot time event)
QTimeEvtCtr QTimeEvt_currCtr(QTimeEvt const *const me)
Get the current value of the down-counter of a time event.
QTimeEvt QTimeEvt_timeEvtHead_[QF_MAX_TICK_RATE]
Array of heads of linked lists of time events (one for every clock tick rate)
bool QTimeEvt_rearm(QTimeEvt *const me, uint32_t const nTicks)
Rearm a time event.
bool QTimeEvt_wasDisarmed(QTimeEvt *const me)
Check the "was disarmed" status of a time event.
bool QTimeEvt_disarm(QTimeEvt *const me)
Disarm a time event.
void * act
Active object that receives the time events.
Attribute of for the QAsm class (Abstract State Machine)
QMTranActTable const * tatbl
struct QMState const * obj