QP/C  7.0.1
Real-Time Embedded Framework
QF Class Reference

QF services (event-driven active object framework) More...

#include <qf.h>

Static Public Member Functions

void QF_init (void)
void QF_psInit (QSubscrList *const subscrSto, enum_t const maxSignal)
void QF_poolInit (void *const poolSto, uint_fast32_t const poolSize, uint_fast16_t const evtSize)
uint_fast16_t QF_poolGetMaxBlockSize (void)
int_t QF_run (void)
void QF_stop (void)
void QF_onStartup (void)
void QF_onCleanup (void)
bool QF_noTimeEvtsActiveX (uint_fast8_t const tickRate)
uint_fast16_t QF_getPoolMin (uint_fast8_t const poolId)
uint_fast16_t QF_getQueueMin (uint_fast8_t const prio)
void QF_bzero (void *const start, uint_fast16_t len)
#define QF_LOG2(n_)   ((uint_fast8_t)(32U - __builtin_clz((unsigned)(n_))))

Public Attributes

uint8_t dummy

Static Private Member Functions

void QF_publish_ (QEvt const *const e, void const *const sender, uint_fast8_t const qs_id)
void QF_tickX_ (uint_fast8_t const tickRate, void const *const sender)
void QF_add_ (QActive *const a)
void QF_remove_ (QActive *const a)
QEvtQF_newX_ (uint_fast16_t const evtSize, uint_fast16_t const margin, enum_t const sig)
QEvt const * QF_newRef_ (QEvt const *const e, void const *const evtRef)
void QF_deleteRef_ (void const *const evtRef)
void QF_gc (QEvt const *const e)

Private Attributes

QTimeEvt QF_timeEvtHead_ [QF_MAX_TICK_RATE]

Static Private Attributes

QActiveQF_active_ [QF_MAX_ACTIVE+1U]
enum_t QF_maxPubSignal_

Detailed Description

This class groups together QF services. It has only static members and should not be instantiated.

Definition at line 781 of file qf.h.

Member Function Documentation

◆ QF_init()

void QF_init ( void  )

QF initialization.

Initializes QF and must be called exactly once before any other QF function. Typically, QF_init() is called from main() even before initializing the Board Support Package (BSP).
QF_init() clears the internal QF variables, so that the framework can start correctly even if the startup code fails to clear the uninitialized data (as is required by the C Standard).

Definition at line 54 of file qk.c.

◆ QF_psInit()

void QF_psInit ( QSubscrList *const  subscrSto,
enum_t const  maxSignal 

Publish-subscribe initialization.

This function initializes the publish-subscribe facilities of QF and must be called exactly once before any subscriptions/publications occur in the application.
[in]subscrStopointer to the array of subscriber lists
[in]maxSignalthe dimension of the subscriber array and at the same time the maximum signal that can be published or subscribed.

The array of subscriber-lists is indexed by signals and provides a mapping between the signals and subscriber-lists. The subscriber-lists are bitmasks of type QSubscrList, each bit in the bit mask corresponding to the unique priority of an active object. The size of the QSubscrList bit mask depends on the value of the QF_MAX_ACTIVE macro.

The publish-subscribe facilities are optional, meaning that you might choose not to use publish-subscribe. In that case calling QF_psInit() and using up memory for the subscriber-lists is unnecessary.
See also
The following example shows the typical initialization sequence of QF:
#include "qpc.h"
int main(void) {
QF_init(); /* initialize the framework and the underlying RT kernel */
BSP_init(); /* initialize the BSP */
/* init publish-subscribe... */
static QSubscrList l_subscrSto[MAX_PUB_SIG];
QF_psInit(l_subscrSto, Q_DIM(l_subscrSto));
/* initialize event pools... */
static QF_MPOOL_EL(TableEvt) l_smlPoolSto[2*N_PHILO]; /* small pool */
QF_poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0]));
/* start the active objects... */
Philo_ctor(); /* instantiate all Philosopher active objects */
static QEvt const *l_philoQueueSto[N_PHILO][N_PHILO];
for (uint8_t n = 0U; n < N_PHILO; ++n) {
QACTIVE_START(AO_Philo[n], (uint8_t)(n + 1),
l_philoQueueSto[n], Q_DIM(l_philoQueueSto[n]),
(void *)0, 0U, (QEvt *)0);
Table_ctor(); /* instantiate the Table active object */
static QEvt const *l_tableQueueSto[N_PHILO];
QACTIVE_START(AO_Table, (uint8_t)(N_PHILO + 1),
l_tableQueueSto, Q_DIM(l_tableQueueSto),
(void *)0, 0U, (QEvt *)0);
return QF_run(); /* run the QF application, QF_run() does not return */
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:205
#define QF_MPOOL_EL(evType_)
Definition: qmpool.h:244
QP/C public interface including backwards-compatibility layer.
Priority Set of up to 64 elements.
Definition: qpset.h:120
Event class.
Definition: qep.h:121
void QF_poolInit(void *const poolSto, uint_fast32_t const poolSize, uint_fast16_t const evtSize)
Definition: qf_dyn.c:63
void QF_psInit(QSubscrList *const subscrSto, enum_t const maxSignal)
Definition: qf_ps.c:54
int_t QF_run(void)
Definition: qk.c:90
void QF_init(void)
Definition: qk.c:54

Definition at line 54 of file qf_ps.c.

◆ QF_poolInit()

void QF_poolInit ( void *const  poolSto,
uint_fast32_t const  poolSize,
uint_fast16_t const  evtSize 

Event pool initialization for dynamic allocation of events.

This function initializes one event pool at a time and must be called exactly once for each event pool before the pool can be used.
[in]poolStopointer to the storage for the event pool
[in]poolSizesize of the storage for the pool in bytes
[in]evtSizethe block-size of the pool in bytes, which determines the maximum size of events that can be allocated from the pool.
You might initialize many event pools by making many consecutive calls to the QF_poolInit() function. However, for the simplicity of the internal implementation, you must initialize event pools in the ascending order of the event size.

Many RTOSes provide fixed block-size heaps, a.k.a. memory pools that can be adapted for QF event pools. In case such support is missing, QF provides a native QF event pool implementation. The macro QF_EPOOL_TYPE_ determines the type of event pool used by a particular QF port. See structure QMPool for more information.

The actual number of events available in the pool might be actually less than (poolSize / evtSize) due to the internal alignment of the blocks that the pool might perform. You can always check the capacity of the pool by calling QF_getPoolMin().
The dynamic allocation of events is optional, meaning that you might choose not to use dynamic events. In that case calling QF_poolInit() and using up memory for the memory blocks is unnecessary.
See also
QF initialization example for QF_init()

Definition at line 63 of file qf_dyn.c.

◆ QF_poolGetMaxBlockSize()

uint_fast16_t QF_poolGetMaxBlockSize ( void  )

Obtain the block size of any registered event pools.

Obtain the block size of any registered event pools

Definition at line 236 of file qf_dyn.c.

◆ QF_run()

int_t QF_run ( void  )

Transfers control to QF to run the application.

QF_run() is typically called from your startup code after you initialize the QF and start at least one active object with QACTIVE_START().
In QK, the QF_run() does not return.

Definition at line 90 of file qk.c.

◆ QF_stop()

void QF_stop ( void  )

Function invoked by the application layer to stop the QF application and return control to the OS/Kernel.

This function stops the QF application. After calling this function, QF attempts to gracefully stop the application. This graceful shutdown might take some time to complete. The typical use of this function is for terminating the QF application to return back to the operating system or for handling fatal errors that require shutting down (and possibly re-setting) the system.
After calling QF_stop() the application must terminate and cannot continue. In particular, QF_stop() is not intended to be followed by a call to QF_init() to "resurrect" the application.
See also

Definition at line 72 of file qk.c.

◆ QF_onStartup()

void QF_onStartup ( void  )

Startup QF callback.

The timeline for calling QF_onStartup() depends on the particular QF port. In most cases, QF_onStartup() is called from QF_run(), right before starting any multitasking kernel or the background loop.

◆ QF_onCleanup()

void QF_onCleanup ( void  )

Cleanup QF callback.

QF_onCleanup() is called in some QF ports before QF returns to the underlying operating system or RTOS.

This function is strongly platform-specific and is not implemented in the QF, but either in the QF port or in the Board Support Package (BSP) for the given application. Some QF ports might not require implementing QF_onCleanup() at all, because many embedded applications don't have anything to exit to.

See also

◆ QF_publish_()

void QF_publish_ ( QEvt const *const  e,
void const *const  sender,
uint_fast8_t const  qs_id 

Publish event to the framework.

This function posts (using the FIFO policy) the event e to all active objects that have subscribed to the signal e->sig, which is called multicasting. The multicasting performed in this function is very efficient based on reference-counting inside the published event ("zero-copy" event multicasting). This function is designed to be callable from any part of the system, including ISRs, device drivers, and active objects.
To avoid any unexpected re-ordering of events posted into AO queues, the event multicasting is performed with scheduler locked. However, the scheduler is locked only up to the priority level of the highest- priority subscriber, so any AOs of even higher priority, which did not subscribe to this event are not affected.
this function should be called only via the macro QF_PUBLISH()

Definition at line 69 of file qf_ps.c.

◆ QF_tickX_()

void QF_tickX_ ( uint_fast8_t const  tickRate,
void const *const  sender 

Processes all armed time events at every clock tick.

This internal helper function processes all armed QTimeEvt objects associated wit the tick rate tickRate .

This function must be called periodically from a time-tick ISR or from a task so that QF can manage the timeout events assigned to the given system clock tick rate.

[in]tickRateclock tick rate serviced in this call [1..15].
[in]senderpointer to a sender object (only for QS tracing)
this function should be called only via the macro QF_TICK_X()
the calls to QF_tickX_() with different tickRate parameter can preempt each other. For example, higher clock tick rates might be serviced from interrupts while others from tasks (active objects).
See also

Definition at line 61 of file qf_time.c.

◆ QF_noTimeEvtsActiveX()

bool QF_noTimeEvtsActiveX ( uint_fast8_t const  tickRate)

Returns 'true' if there are no armed time events at a given tick rate.

Find out if any time events are armed at the given clock tick rate.
[in]tickRatesystem clock tick rate to find out about.
'true' if no time events are armed at the given tick rate and 'false' otherwise.
This function should be called in critical section.

Definition at line 163 of file qf_time.c.

◆ QF_add_()

void QF_add_ ( QActive *const  a)

Register an active object to be managed by the framework.

This function adds a given active object to the active objects managed by the QF framework. It should not be called by the application directly, only by the QP ports.
[in]apointer to the active object to add to the framework.
The priority of the active object a should be set before calling this function.
See also

Definition at line 51 of file qf_act.c.

◆ QF_remove_()

void QF_remove_ ( QActive *const  a)

Remove the active object from the framework.

This function removes a given active object from the active objects managed by the QF framework. It should not be called by the application directly, only by the QP ports.
[in]apointer to the active object to remove from the framework.
The active object that is removed from the framework can no longer participate in the publish-subscribe event exchange.
See also

Definition at line 69 of file qf_act.c.

◆ QF_getPoolMin()

uint_fast16_t QF_getPoolMin ( uint_fast8_t const  poolId)

Obtain the minimum of free entries of the given event pool.

This function obtains the minimum number of free blocks in the given event pool since this pool has been initialized by a call to QF_poolInit().
[in]poolIdevent pool ID in the range 1..QF_maxPool_, where QF_maxPool_ is the number of event pools initialized with the function QF_poolInit().
the minimum number of unused blocks in the given event pool.

Definition at line 189 of file qf_mem.c.

◆ QF_getQueueMin()

uint_fast16_t QF_getQueueMin ( uint_fast8_t const  prio)

This function returns the minimum of free entries of the given event queue.

Queries the minimum of free ever present in the given event queue of an active object with priority prio, since the active object was started.
This function is available only when the native QF event queue implementation is used. Requesting the queue minimum of an unused priority level raises an assertion in the QF. (A priority level becomes used in QF after the call to the QF_add_() function.)
[in]prioPriority of the active object, whose queue is queried
the minimum of free ever present in the given event queue of an active object with priority prio, since the active object was started.

Definition at line 285 of file qf_actq.c.

◆ QF_newX_()

QEvt * QF_newX_ ( uint_fast16_t const  evtSize,
uint_fast16_t const  margin,
enum_t const  sig 

Internal QF implementation of creating new dynamic event.

Allocates an event dynamically from one of the QF event pools.
[in]evtSizethe size (in bytes) of the event to allocate
[in]marginthe number of un-allocated events still available in a given event pool after the allocation completes. The special value QF_NO_MARGIN means that this function will assert if allocation fails.
[in]sigthe signal to be assigned to the allocated event
pointer to the newly allocated event. This pointer can be NULL only if margin != QF_NO_MARGIN and the event cannot be allocated with the specified margin still available in the given pool.
The internal QF function QF_newX_() raises an assertion when the margin parameter is QF_NO_MARGIN and allocation of the event turns out to be impossible due to event pool depletion, or incorrect (too big) size of the requested event.
The application code should not call this function directly. The only allowed use is thorough the macros Q_NEW() or Q_NEW_X().

Definition at line 89 of file qf_dyn.c.

◆ QF_newRef_()

QEvt const * QF_newRef_ ( QEvt const *const  e,
void const *const  evtRef 

Internal QF implementation of creating new event reference.

Creates and returns a new reference to the current event e
[in]epointer to the current event
[in]evtRefthe event reference
the newly created reference to the event e
The application code should not call this function directly. The only allowed use is thorough the macro Q_NEW_REF().

Definition at line 195 of file qf_dyn.c.

◆ QF_deleteRef_()

void QF_deleteRef_ ( void const *const  evtRef)

Internal QF implementation of deleting event reference.

Deletes an existing reference to the event e
[in]evtRefthe event reference
The application code should not call this function directly. The only allowed use is thorough the macro Q_DELETE_REF().

Definition at line 221 of file qf_dyn.c.

◆ QF_gc()

void QF_gc ( QEvt const *const  e)

Recycle a dynamic event

This function implements a simple garbage collector for the dynamic events. Only dynamic events are candidates for recycling. (A dynamic event is one that is allocated from an event pool, which is determined as non-zero e->poolId_ attribute.) Next, the function decrements the reference counter of the event (e->refCtr_), and recycles the event only if the counter drops to zero (meaning that no more references are outstanding for this event). The dynamic event is recycled by returning it to the pool from which it was originally allocated.
[in]epointer to the event to recycle
QF invokes the garbage collector at all appropriate contexts, when an event can become garbage (automatic garbage collection), so the application code should have no need to call QF_gc() directly. The QF_gc() function is exposed only for special cases when your application sends dynamic events to the "raw" thread-safe queues (see QEQueue). Such queues are processed outside of QF and the automatic garbage collection is NOT performed for these events. In this case you need to call QF_gc() explicitly.

Definition at line 146 of file qf_dyn.c.

◆ QF_bzero()

void QF_bzero ( void *const  start,
uint_fast16_t  len 

Clear a specified region of memory to zero.

Clears a memory buffer by writing zeros byte-by-byte.
[in]startpointer to the beginning of a memory buffer.
[in]lenlength of the memory buffer to clear (in bytes)
The main application of this function is clearing the internal QF variables upon startup. This is done to avoid problems with non-standard startup code provided with some compilers and toolsets (e.g., TI DSPs or Microchip MPLAB), which does not zero the uninitialized variables, as required by the ANSI C standard.

Definition at line 86 of file qf_act.c.

Member Data Documentation

◆ dummy

uint8_t dummy

Definition at line 782 of file qf.h.

◆ QF_timeEvtHead_

QTimeEvt QF_timeEvtHead_

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

Definition at line 240 of file qf_pkg.h.

◆ QF_active_

QActive* QF_active_[QF_MAX_ACTIVE+1U]

Definition at line 48 of file qf_act.c.

◆ QF_subscrList_

QSubscrList* QF_subscrList_

Definition at line 48 of file qf_ps.c.

◆ QF_maxPubSignal_

enum_t QF_maxPubSignal_

Definition at line 51 of file qf_ps.c.

The documentation for this class was generated from the following files: