QP/C  7.2.2
Real-Time Embedded Framework
Loading...
Searching...
No Matches
qf.h File Reference

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

Go to the source code of this file.

Classes

class  QPSet
 Priority Set of up to QF_MAX_ACTIVE elements. More...
 
class  QActive
 Active object class (based on the QHsm implementation strategy) More...
 
struct  QActiveVtable
 Virtual table for the QActive class. More...
 
class  QMActive
 Active object class (based on QMsm implementation strategy) More...
 
class  QTimeEvt
 Time Event class. More...
 
class  QTicker
 "Ticker" Active Object class More...
 
class  QF
 QF active object framework. More...
 

Macros

#define QF_NO_MARGIN   ((uint_fast16_t)0xFFFFU)
 
#define Q_PRIO(prio_, pthre_)   ((QPrioSpec)((prio_) | ((pthre_) << 8U)))
 
#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 QACTIVE_START(me_, prioSpec_, qSto_, qLen_, stkSto_, stkSize_, par_)
 
#define QACTIVE_POST(me_, e_, sender_)
 
#define QACTIVE_POST_X(me_, e_, margin_, sender_)
 
#define QACTIVE_POST_LIFO(me_, e_)
 
#define QACTIVE_PUBLISH(e_, sender_)    (QActive_publish_((e_), (void const *)(sender_), (sender_)->prio))
 
#define QTIMEEVT_TICK_X(tickRate_, sender_)    (QTimeEvt_tick_((tickRate_), (sender_)))
 
#define QTIMEEVT_TICK(sender_)   QTIMEEVT_TICK_X(0U, (sender_))
 
#define QF_CRIT_EXIT_NOP()   ((void)0)
 
#define QF_TICK_X(tickRate_, sender_)   QTIMEEVT_TICK_X((tickRate_), (sender_))
 
#define QF_TICK(sender_)   QTIMEEVT_TICK(sender_)
 
#define QF_PUBLISH(e_, sender_)   QACTIVE_PUBLISH((e_), (sender_))
 

Typedefs

typedef uint32_t QPSetBits
 
typedef uint32_t QTimeEvtCtr
 
typedef uint16_t QPrioSpec
 
typedef uint_fast16_t QSchedStatus
 
typedef QPSet QSubscrList
 
typedef QActiveVtable QMActiveVtable
 Virtual Table for the QMActive class (inherited from QActiveVtable)
 

Functions

static void QPSet_setEmpty (QPSet *const me)
 
static bool QPSet_isEmpty (QPSet const *const me)
 
static bool QPSet_notEmpty (QPSet const *const me)
 
static bool QPSet_hasElement (QPSet const *const me, uint_fast8_t const n)
 
static void QPSet_insert (QPSet *const me, uint_fast8_t const n)
 
static void QPSet_remove (QPSet *const me, uint_fast8_t const n)
 
static uint_fast8_t QPSet_findMax (QPSet const *const me)
 
static void QF_psInit (QSubscrList *const subscrSto, enum_t const maxSignal)
 

Variables

QTimeEvt QTimeEvt_timeEvtHead_ [QF_MAX_TICK_RATE]
 

Class Documentation

◆ QPSet

class QPSet

The priority set represents the set of active objects that are ready to run and need to be considered by the scheduling algorithm. The set is capable of storing up to QF_MAX_ACTIVE priority levels, which can be configured in the rage 1..64, inclusive.

Definition at line 229 of file qf.h.

Class Members
QPSetBits volatile bits

bitmask with a bit for each element

Macro Definition Documentation

◆ 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 1751 of file qf.h.

◆ Q_PRIO

#define Q_PRIO (   prio_,
  pthre_ 
)    ((QPrioSpec)((prio_) | ((pthre_) << 8U)))

Create a QPrioSpec object to specify priorty of an AO or a thread

Definition at line 1755 of file qf.h.

◆ Q_NEW

#define Q_NEW (   evtT_,
  sig_,
  ... 
)
Value:
(evtT_##_ctor((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \
QF_NO_MARGIN, (sig_)), (enum_t)(sig_), ##__VA_ARGS__))
int enum_t
Definition: qep.h:76
#define QF_NO_MARGIN
Definition: qf.h:1751

Asserting allocate a dynamic event (case when QEvt is not a POD)

Definition at line 1790 of file qf.h.

◆ Q_NEW_X

#define Q_NEW_X (   e_,
  evtT_,
  margin_,
  sig_,
  ... 
)
Value:
do { \
(e_) = (evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \
(margin_), (enum_t)(sig_));\
if ((e_) != (evtT_ *)0) { \
evtT_##_ctor((e_), (enum_t)(sig_), ##__VA_ARGS__); \
} \
} while (false)

Non-asserting allocate a dynamic event (case when QEvt is not a POD)

Definition at line 1834 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 1864 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 1883 of file qf.h.

◆ QACTIVE_START

#define QACTIVE_START (   me_,
  prioSpec_,
  qSto_,
  qLen_,
  stkSto_,
  stkSize_,
  par_ 
)
Value:
do { \
Q_ASSERT((Q_HSM_UPCAST(me_))->vptr); \
(*((QActiveVtable const *)((Q_HSM_UPCAST(me_))->vptr))->start)( \
(QActive *)(me_), (prioSpec_), \
(qSto_), (qLen_), (stkSto_), (stkSize_), (par_)); \
} while (false)
#define Q_HSM_UPCAST(ptr_)
Definition: qep.h:948
Active object class (based on the QHsm implementation strategy)
Definition: qf.h:372
Virtual table for the QActive class.
Definition: qf.h:931

Virtual call to start an active object.

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

Parameters
[in,out]me_current instance pointer (see oop)
[in]prioSpec_priority specification for 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"
Q_DEFINE_THIS_FILE
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_DIM(array_)
Definition: qassert.h:424
#define QACTIVE_START(me_, prioSpec_, qSto_, qLen_, stkSto_, stkSize_, par_)
Definition: qf.h:1907
QP/C public interface including backwards-compatibility layer.
int_t QF_run(void)
Definition: qutest.c:190
void QF_init(void)
Definition: qutest.c:171
Event class.
Definition: qep.h:167

Definition at line 1907 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_)))

Invoke the direct event posting facility QActive_post_()

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

Parameters
[in,out]me_current instance 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_ 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, 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_()

Definition at line 1939 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_)))

Invoke the direct event posting facility QActive_post_() 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_current instance 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 posting 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 entries 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 POST_X() macro does not pass 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, if 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 Q_NEW_X(e_, evtT_, margin_, sig_,...)
Definition: qf.h:1834
#define QACTIVE_POST_X(me_, e_, margin_, sender_)
Definition: qf.h:1988

Definition at line 1988 of file qf.h.

◆ QACTIVE_POST_LIFO

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

Virtual call to post an event to an active object using the Last-In-First-Out (LIFO) policy.

Parameters
[in,out]me_current instance pointer (see oop)
[in]e_pointer to the event to post

Definition at line 2007 of file qf.h.

◆ QACTIVE_PUBLISH

#define QACTIVE_PUBLISH (   e_,
  sender_ 
)     (QActive_publish_((e_), (void const *)(sender_), (sender_)->prio))

Publish an event to all subscriber Active Objects.

If Q_SPY is defined, this macro calls QActive_publish_() with the sender_ parameter to identify the publisher of the event. Otherwise, sender_ is not used.

Parameters
[in]e_pointer to the posted event
[in]sender_pointer to the sender object (actually used only when Q_SPY is defined)
Note
The pointer to the sender_ object is not necessarily a pointer to an active object. In fact, if QACTIVE_PUBLISH() 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_publish_()

Definition at line 2032 of file qf.h.

◆ QTIMEEVT_TICK_X

#define QTIMEEVT_TICK_X (   tickRate_,
  sender_ 
)     (QTimeEvt_tick_((tickRate_), (sender_)))

Invoke the system clock tick processing QTimeEvt_tick_()

This macro is the recommended way of invoking clock tick processing, because it provides the vital information for software tracing and avoids any overhead when the tracing is disabled.

Parameters
[in]tickRate_clock tick rate to be serviced through this call
[in]sender_pointer to the sender object. This parameter is actually only used when QS software tracing is enabled (macro Q_SPY is defined)
Note
When QS software tracing is disabled, the macro calls QTimeEvt_tick_() 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 QTIMEEVT_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.
See also
QTimeEvt_tick_()

Definition at line 2067 of file qf.h.

◆ QTIMEEVT_TICK

#define QTIMEEVT_TICK (   sender_)    QTIMEEVT_TICK_X(0U, (sender_))

Invoke the system clock tick processing for tick rate 0

Definition at line 2081 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 adjecent critical sections would be merged. The QF_CRIT_EXIT_NOP() macro contains minimal code required to prevent such merging of critical sections in such merging of critical sections in QF ports, in which it can occur.

Definition at line 2096 of file qf.h.

◆ QF_TICK_X

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

Invoke the system clock tick processing

Deprecated:
superseded by QTIMEEVT_TICK_X()

Definition at line 2105 of file qf.h.

◆ QF_TICK

#define QF_TICK (   sender_)    QTIMEEVT_TICK(sender_)

Invoke the system clock tick processing for tick rate 0

Deprecated:
superseded by QTIMEEVT_TICK()

Definition at line 2113 of file qf.h.

◆ QF_PUBLISH

#define QF_PUBLISH (   e_,
  sender_ 
)    QACTIVE_PUBLISH((e_), (sender_))

Publish an event to all subscriber Active Objects.

Deprecated:
superseded by QACTIVE_PUBLISH()

Definition at line 2121 of file qf.h.

Typedef Documentation

◆ QPSetBits

typedef uint32_t QPSetBits

Definition at line 129 of file qf.h.

◆ QTimeEvtCtr

typedef uint32_t QTimeEvtCtr

Definition at line 151 of file qf.h.

◆ QPrioSpec

typedef uint16_t QPrioSpec

Priority specification for Active Objects in QP

Active Object priorities in QP are integer numbers in the range [1..QF_MAX_ACTIVE], whereas the special priority number 0 is reserved for the lowest-priority idle thread. The QP framework uses the direct priority numbering, in which higher numerical values denote higher urgency. For example, an AO with priority 32 has higher urgency than an AO with priority 23.

QPrioSpec allows an application developer to assign two priorities to a given AO (see also Q_PRIO()):

  1. The "QF-priority", which resides in the least-significant byte of the QPrioSpec data type. The "QF-priority" must be unique for each thread in the system and higher numerical values represent higher urgency (direct pirority numbering).
  2. The "preemption-threshold" priority, which resides in the most- significant byte of the QPrioSpec data type. The second priority cannot be lower than the "QF-priority", but does NOT need to be unuque.

In the QP native preemptive kernels, like QK and QXK, the "preemption- threshold" priority is used as to implement the "preemption-threshold scheduling" (PTS). It determines the conditions under which a given thread can be preempted by other threads. Specifically, a given thread can be preempted only by another thread with a higher priority than the "preemption-threshold" of the original thread.

QF-priority and preemption-threshold relations
Note
For backwards-compatibility, QPrioSpec data type might contain only the "QF-priority" component (and the "preemption-threshold" component left at zero). In that case, the "preemption-threshold" will be assumed to be the same as the "QF-priority". This corresponds exactly to the previous semantics of AO priority.
Remarks
When QP runs on top of 3rd-party kernels/RTOSes or general-purpose operating systems, sthe second priority can have different meaning, depending on the specific RTOS/GPOS used.

Definition at line 213 of file qf.h.

◆ QSchedStatus

typedef uint_fast16_t QSchedStatus

The scheduler lock status used in some real-time kernels

Definition at line 217 of file qf.h.

◆ QSubscrList

typedef QPSet QSubscrList

Subscriber List (for publish-subscribe)

This data type represents a set of Active Objects that subscribe to a given signal. The set is represented as priority-set, where each bit corresponds to the unique QF-priority of an AO (see QPrioSpec).

Definition at line 338 of file qf.h.

◆ QMActiveVtable

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

Definition at line 1018 of file qf.h.

Function Documentation

◆ QPSet_setEmpty()

static void QPSet_setEmpty ( QPSet *const  me)
inlinestatic

Make the priority set empty

Definition at line 246 of file qf.h.

◆ QPSet_isEmpty()

static bool QPSet_isEmpty ( QPSet const *const  me)
inlinestatic

Return 'true' if the priority set is empty

Definition at line 256 of file qf.h.

◆ QPSet_notEmpty()

static bool QPSet_notEmpty ( QPSet const *const  me)
inlinestatic

Return 'true' if the priority set is NOT empty

Definition at line 265 of file qf.h.

◆ QPSet_hasElement()

static bool QPSet_hasElement ( QPSet const *const  me,
uint_fast8_t const  n 
)
inlinestatic

Return 'true' if the priority set has the element n.

Definition at line 274 of file qf.h.

◆ QPSet_insert()

static void QPSet_insert ( QPSet *const  me,
uint_fast8_t const  n 
)
inlinestatic

insert element n into the set (n = 1..QF_MAX_ACTIVE)

Definition at line 287 of file qf.h.

◆ QPSet_remove()

static void QPSet_remove ( QPSet *const  me,
uint_fast8_t const  n 
)
inlinestatic

Remove element n from the set (n = 1U..QF_MAX_ACTIVE)

Definition at line 303 of file qf.h.

◆ QPSet_findMax()

static uint_fast8_t QPSet_findMax ( QPSet const *const  me)
inlinestatic

Find the maximum element in the set, returns zero if the set is empty

Definition at line 320 of file qf.h.

◆ QF_psInit()

static void QF_psInit ( QSubscrList *const  subscrSto,
enum_t const  maxSignal 
)
inlinestatic

initialization of publish-subscribe

Deprecated:
See also
QActive_psInit()

Definition at line 1482 of file qf.h.

Variable Documentation

◆ QTimeEvt_timeEvtHead_

QTimeEvt QTimeEvt_timeEvtHead_[QF_MAX_TICK_RATE]
extern

heads of linked lists of time events, one for every clock tick rate