QP/C  7.0.0
Real-Time Embedded Framework
qf.h File Reference

QF/C platform-independent public interface. More...

#include "qpset.h"

Go to the source code of this file.

Data Structures

struct  QActive
 
struct  QActiveVtable
 
struct  QMActive
 
struct  QTimeEvt
 
struct  QF
 
struct  QTicker
 

Macros

#define QACTIVE_START(me_, prio_, qSto_, qLen_, stkSto_, stkLen_, par_)
 
#define QACTIVE_POST(me_, e_, sender_)
 
#define QACTIVE_POST_X(me_, e_, margin_, sender_)
 
#define QACTIVE_POST_LIFO(me_, e_)
 
#define QF_PUBLISH(e_, sender_)    (QF_publish_((e_), (void const *)(sender_), (sender_)->prio))
 
#define QF_TICK_X(tickRate_, sender_)   (QF_tickX_((tickRate_), (sender_)))
 
#define QF_NO_MARGIN   ((uint_fast16_t)0xFFFFU)
 
#define QF_TICK(sender_)   QF_TICK_X(0U, (sender_))
 
#define Q_NEW(evtT_, sig_)
 
#define Q_NEW_X(e_, evtT_, margin_, sig_)
 
#define Q_NEW_REF(evtRef_, evtT_)    ((evtRef_) = (evtT_ const *)QF_newRef_(e, (evtRef_)))
 
#define Q_DELETE_REF(evtRef_)
 
#define QF_CRIT_EXIT_NOP()   ((void)0)
 

Typedefs

typedef uint8_t QEvtSize
 
typedef QActiveVtable QMActiveVtable
 
typedef uint8_t QTimeEvtCtr
 
typedef QPSet QSubscrList
 

Variables

QActiveQF_active_ [QF_MAX_ACTIVE+1U]
 

Detailed Description

Date
Last updated on: 2021-12-23
Version
Last updated for: Version 7.0.0, 2022-04-30

Definition in file qf.h.

Macro Definition Documentation

◆ QACTIVE_START

#define QACTIVE_START (   me_,
  prio_,
  qSto_,
  qLen_,
  stkSto_,
  stkLen_,
  par_ 
)
Value:
do { \
Q_ASSERT((Q_HSM_UPCAST(me_))->vptr); \
(*((QActiveVtable const *)((Q_HSM_UPCAST(me_))->vptr))->start)( \
(QActive *)(me_), (prio_), \
(qSto_), (qLen_), (stkSto_), (stkLen_), (par_)); \
} while (false)
#define Q_HSM_UPCAST(ptr_)
Definition: qep.h:365
Definition: qf.h:107

Polymorphically start an active object.

Starts execution of the AO and registers the AO with the framework.

Parameters
[in,out]me_pointer (see oop)
[in]prio_priority at which to start the active object
[in]qSto_pointer to the storage for the ring buffer of the event queue (used only with the built-in QEQueue)
[in]qLen_length of the event queue (in events)
[in]stkSto_pointer to the stack storage (used only when per-AO stack is needed)
[in]stkSize_stack size (in bytes)
[in]par_pointer to the additional port-specific parameter(s) (might be NULL).
Usage
#include "qpc.h"
int main() {
QF_init(); /* initialize the framework and the underlying RT kernel */
BSP_init(); /* initialize the Board Support Package */
. . .
/* instantiate and start the active objects... */
Blinky_ctor();
static QEvt const *l_blinkyQSto[10]; /* Event queue storage for Blinky */
QACTIVE_START(AO_Blinky, /* AO pointer to start */
1U, /* unique QP priority of the AO */
l_blinkyQSto, /* storage for the AO's queue */
Q_DIM(l_blinkyQSto), /* lenght of the queue [entries] */
(void *)0, /* stack storage (not used in QK) */
0U, /* stack size [bytes] (not used in QK) */
(void *)0); /* initialization parameter (or 0) */
. . .
return QF_run(); /* run the QF application */
}
#define Q_DEFINE_THIS_FILE
Definition: qassert.h:87
#define Q_DIM(array_)
Definition: qassert.h:307
#define QACTIVE_START(me_, prio_, qSto_, qLen_, stkSto_, stkLen_, par_)
Definition: qf.h:206
QP/C public interface including backwards-compatibility layer.
Definition: qep.h:119
int_t QF_run(void)
Definition: qk.c:124
void QF_init(void)
Definition: qk.c:64

Definition at line 206 of file qf.h.

◆ QACTIVE_POST

#define QACTIVE_POST (   me_,
  e_,
  sender_ 
)
Value:
((void)(*((QActiveVtable const *)((Q_HSM_UPCAST(me_))->vptr))->post)(\
(me_), (e_), QF_NO_MARGIN, (sender_)))
#define QF_NO_MARGIN
Definition: qf.h:687

Polymorphically posts an event to an active object (FIFO) with delivery guarantee.

This macro asserts if the queue overflows and cannot accept the event.

Parameters
[in,out]me_pointer (see oop)
[in]e_pointer to the event to post
[in]sender_pointer to the sender object.
Note
The sendedr_ parameter is actually only used when QS tracing is enabled (macro Q_SPY is defined). When QS software tracing is disenabled, the QACTIVE_POST() macro does not pass the sender_ argument, so the overhead of passing this extra argument is entirely avoided.
The pointer to the sender object is not necessarily a pointer to an active object. In fact, if QACTIVE_POST() is called from an interrupt or other context, you can create a unique object just to unambiguously identify the sender of the event.
See also
QACTIVE_POST_X, QActive_post_().

Definition at line 238 of file qf.h.

◆ QACTIVE_POST_X

#define QACTIVE_POST_X (   me_,
  e_,
  margin_,
  sender_ 
)
Value:
((*((QActiveVtable const *)((Q_HSM_UPCAST(me_))->vptr))->post)((me_),\
(e_), (margin_), (sender_)))

Polymorphically posts an event to an active object (FIFO) without delivery guarantee.

This macro does not assert if the queue overflows and cannot accept the event with the specified margin of free slots remaining.

Parameters
[in,out]me_pointer (see oop)
[in]e_pointer to the event to post
[in]margin_the minimum free slots in the queue, which must still be available after posting the event. The special value QF_NO_MARGIN causes asserting failure in case event allocation fails.
[in]sender_pointer to the sender object.
Returns
'true' if the posting succeeded, and 'false' if the posting failed due to insufficient margin of free slots available in the queue.
Note
The sender_ parameter is actually only used when QS tracing is enabled (macro Q_SPY is defined). When QS software tracing is disabled, the QACTIVE_POST() macro does not pass the sender_ argument, so the overhead of passing this extra argument is entirely avoided.
The pointer to the sender object is not necessarily a pointer to an active object. In fact, if QACTIVE_POST_X() is called from an interrupt or other context, you can create a unique object just to unambiguously identify the sender of the event.
Usage
extern QActive * const AO_Table;
. . .
/* typically inside a state machine action */
TableEvt *pe;
Q_NEW_X(pe, TableEvt, 5U, HUNGRY_SIG); /* dynamic alloc, margin==5 */
if (pe != (TableEvt *)0) {
pe->philNum = me->num;
QACTIVE_POST_X(AO_Table, &pe->super, 3U, me); /* <--- */
}
. . .
#define QACTIVE_POST_X(me_, e_, margin_, sender_)
Definition: qf.h:275
#define Q_NEW_X(e_, evtT_, margin_, sig_)
Definition: qf.h:803

Definition at line 275 of file qf.h.

◆ QACTIVE_POST_LIFO

#define QACTIVE_POST_LIFO (   me_,
  e_ 
)
Value:
((*((QActiveVtable const *)((Q_HSM_UPCAST(me_))->vptr))->postLIFO)( \
(me_), (e_)))

Polymorphically posts an event to an active object using the Last-In-First-Out (LIFO) policy.

Parameters
[in,out]me_pointer (see oop)
[in]e_pointer to the event to post

Definition at line 295 of file qf.h.

◆ QF_PUBLISH

#define QF_PUBLISH (   e_,
  sender_ 
)     (QF_publish_((e_), (void const *)(sender_), (sender_)->prio))

Invoke the event publishing facility.

This macro is the recommended way of publishing events, because it provides the vital information for software tracing and avoids any overhead when the tracing is disabled.

Parameters
[in]e_pointer to the posted event
[in]sender_pointer to the sender object. This argument is actually only used when QS software tracing is enabled (macro Q_SPY is defined). When QS software tracing is disabled, the macro calls QF_publish_() without the sender_ parameter, so the overhead of passing this extra argument is entirely avoided.
Note
the pointer to the sender object is not necessarily a pointer to an active object. In fact, if QF_PUBLISH() is called from an interrupt or other context, you can create a unique object just to unambiguously identify the publisher of the event.
See also
QF_publish_().

Definition at line 626 of file qf.h.

◆ QF_TICK_X

#define QF_TICK_X (   tickRate_,
  sender_ 
)    (QF_tickX_((tickRate_), (sender_)))

Invoke the system clock tick processing QF_tickX_().

This macro processes all armed QTimeEvt objects associated with the tick rate tickRate_ .

Parameters
[in]tickRate_clock tick rate to be serviced through this call
[in]sender_pointer to the sender object. This parameter is actually used only when QS software tracing is enabled (macro Q_SPY is defined)
Note
When QS software tracing is disabled, the macro calls QF_tickX_() without the sender_ parameter, so the overhead of passing this extra parameter is entirely avoided.
The pointer to the sender object is not necessarily a pointer to an active object. In fact, when QF_TICK_X() is called from an interrupt, you would create a unique object just to unambiguously identify the ISR as the sender of the time events.
Usage
The following example shows how to invoke QF_TICK_X() for different system tick rates:
#ifdef Q_SPY
/* QS-ID for local filtering */
static QSpyId const l_ISR_timer = { QS_AP_ID + 5 };
#endif
/* case 1: Interrupt Controller available,
* "unconditional interrupt unlocking" critical section policy
* (nesting of critical sections _not_ allowed)
*/
interrupt void ISR_timer() { /* entered with interrupts disabled in hardware */
QF_INT_ENABLE(); /* enable interrupts */
QF_TICK_X(0U, &l_ISR_timer); /* <--- call the QF tick processing */
QF_INT_DISABLE(); /* disable interrupts again */
/* send the EOI instruction to the Interrupt Controller */
}
/* case 2: Interrupt Controller not used,
* "saving and restoring interrupt status" critical section policy
* (nesting of critical sections allowed)
*/
interrupt void ISR_timer() {
QF_TICK_X(1U, &l_ISR_timer); /* <--- call the QF tick processing */
}
#define QF_TICK_X(tickRate_, sender_)
Definition: qf.h:675
@ QS_AP_ID
Definition: qs.h:191
Definition: qs.h:204
#define QF_INT_DISABLE()
#define QF_INT_ENABLE()
See also
QTimeEvt
QTimeEvt_ctorX()
QF_tickX_()
QF_TICK()
QXThread_ctor()
QXThread_delay()

Definition at line 675 of file qf.h.

◆ QF_NO_MARGIN

#define QF_NO_MARGIN   ((uint_fast16_t)0xFFFFU)

special value of margin that causes asserting failure in case event allocation or event posting fails

Definition at line 687 of file qf.h.

◆ QF_TICK

#define QF_TICK (   sender_)    QF_TICK_X(0U, (sender_))

Invoke the system clock tick processing for tick rate 0

See also
QF_TICK_X()

Definition at line 692 of file qf.h.

◆ Q_NEW

#define Q_NEW (   evtT_,
  sig_ 
)
Value:
((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \
QF_NO_MARGIN, (enum_t)(sig_)))
signed int enum_t
Definition: qep.h:60
QEvt * QF_newX_(uint_fast16_t const evtSize, uint_fast16_t const margin, enum_t const sig)
Definition: qf_dyn.c:160

Allocate a dynamic event.

The macro calls the internal QF function QF_newX_() with margin == QF_NO_MARGIN, which causes an assertion when the event cannot be successfully allocated.

Parameters
[in]evtT_event type (class name) of the event to allocate
[in]sig_signal to assign to the newly allocated event
Returns
a valid event pointer cast to the type evtT_.
Note
If Q_EVT_CTOR is defined, the Q_NEW() macro becomes variadic and takes all the arguments needed by the constructor of the event class being allocated. The constructor is then called by means of the placement-new operator.
Usage
The following example illustrates dynamic allocation of an event:
extern QActive * const AO_Table;
QState Philoso_hungry(Philo * const me, QEvt const * const e) {
QState status;
switch (e->sig) {
case Q_ENTRY_SIG: {
TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); /* dynamic alloc */
pe->philNum = me->num;
QACTIVE_POST(AO_Table, &pe->super, me); /* <--- */
status = Q_HANDLED();
break;
}
. . .
default: {
status = Q_SUPER(&QHsm_top);
break;
}
}
return status;
}
#define Q_HANDLED()
Definition: qep.h:554
uint_fast8_t QState
Definition: qep.h:170
#define Q_SUPER(super_)
Definition: qep.h:548
@ Q_ENTRY_SIG
Definition: qep.h:688
#define QACTIVE_POST(me_, e_, sender_)
Definition: qf.h:238
#define Q_NEW(evtT_, sig_)
Definition: qf.h:773
QSignal sig
Definition: qep.h:123
QState QHsm_top(void const *const me, QEvt const *const e)
Definition: qep_hsm.c:261

Definition at line 773 of file qf.h.

◆ Q_NEW_X

#define Q_NEW_X (   e_,
  evtT_,
  margin_,
  sig_ 
)
Value:
((e_) = \
(evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \
(margin_), (enum_t)(sig_)))

Allocate a dynamic event (non-asserting version).

This macro allocates a new event and sets the pointer e_, while leaving at least margin_ of events still available in the pool

Parameters
[in,out]e_pointer to the newly allocated event
[in]evtT_event type (class name) of the event to allocate
[in]margin_number of events that must remain available in the given pool after this allocation. The special value QF_NO_MARGIN causes asserting failure in case event allocation or event posting fails.
[in]sig_signal to assign to the newly allocated event
Returns
an event pointer cast to the type evtT_ or NULL if the event cannot be allocated with the specified margin.
Note
If Q_EVT_CTOR is defined, the Q_NEW_X() macro becomes variadic and takes all the arguments needed by the constructor of the event class being allocated. The constructor is then called and all the extra arguments are passed to it.
Usage
The following example illustrates dynamic allocation of an event:
extern QActive * const AO_Table;
. . .
/* typically inside a state machine action */
TableEvt *pe;
Q_NEW_X(pe, TableEvt, 5U, HUNGRY_SIG); /* dynamic alloc, margin==5 */
if (pe != (TableEvt *)0) {
pe->philNum = me->num;
QACTIVE_POST_X(AO_Table, &pe->super, 3U, me); /* <--- */
}
. . .

Definition at line 803 of file qf.h.

◆ Q_NEW_REF

#define Q_NEW_REF (   evtRef_,
  evtT_ 
)     ((evtRef_) = (evtT_ const *)QF_newRef_(e, (evtRef_)))

Create a new reference of the current event e

The current event processed by an active object is available only for the duration of the run-to-completion (RTC) step. After that step, the current event is no longer available and the framework might recycle (garbage-collect) the event. The macro Q_NEW_REF() explicitly creates a new reference to the current event that can be stored and used beyond the current RTC step, until the reference is explicitly recycled by means of the macro Q_DELETE_REF().

Parameters
[in,out]evtRef_event reference to create
[in]evtT_event type (class name) of the event reference
Usage
The example defer in the directory examples/win32/defer illustrates the use of Q_NEW_REF()
See also
Q_DELETE_REF()

Definition at line 828 of file qf.h.

◆ Q_DELETE_REF

#define Q_DELETE_REF (   evtRef_)
Value:
do { \
QF_deleteRef_((evtRef_)); \
(evtRef_) = (void *)0; \
} while (false)

Delete the event reference

Every event reference created with the macro Q_NEW_REF() needs to be eventually deleted by means of the macro Q_DELETE_REF() to avoid leaking the event.

Parameters
[in,out]evtRef_event reference to delete
Usage
The example defer in the directory examples/win32/defer illustrates the use of Q_DELETE_REF()
See also
Q_NEW_REF()

Definition at line 845 of file qf.h.

◆ QF_CRIT_EXIT_NOP

#define QF_CRIT_EXIT_NOP ( )    ((void)0)

No-operation for exiting a critical section

In some QF ports the critical section exit takes effect only on the next machine instruction. If this next instruction is another entry to a critical section, the critical section won't be really exited, but rather the two adjacent critical sections would be merged. The QF_CRIT_EXIT_NOP() macro contains minimal code required to prevent such merging of critical sections in QF ports, in which it can occur.

Definition at line 871 of file qf.h.

Typedef Documentation

◆ QEvtSize

typedef uint8_t QEvtSize

Definition at line 45 of file qf.h.

◆ QMActiveVtable

Virtual Table for the QMActive class (inherited from QActiveVtable

Note
QMActive inherits QActive exactly, without adding any new virtual functions and therefore, QMActiveVtable is typedef'ed as QActiveVtable.

Definition at line 387 of file qf.h.

◆ QTimeEvtCtr

typedef uint8_t QTimeEvtCtr

Definition at line 397 of file qf.h.

◆ QSubscrList

typedef QPSet QSubscrList

Subscriber-List structure

This data type represents a set of active objects that subscribe to a given signal. The set is represented as a priority-set, where each bit corresponds to the unique priority of an active object.

See also
QSubscrList for the description of the data members

Definition at line 536 of file qf.h.

Variable Documentation

◆ QF_active_

QActive* QF_active_[QF_MAX_ACTIVE+1U]
extern

array of registered active objects

Note
Not to be used by Clients directly, only in ports of QF