QP/C++
Static Public Member Functions | Static Public Attributes | Friends
QF Class Reference

QF services. More...

#include <qf.h>

List of all members.

Static Public Member Functions

static void init (void)
 QF initialization.
static void psInit (QSubscrList *const subscrSto, uint32_t const maxSignal)
 Publish-subscribe initialization.
static void poolInit (void *const poolSto, uint32_t const poolSize, uint32_t const evtSize)
 Event pool initialization for dynamic allocation of events.
static int16_t run (void)
 Transfers control to QF to run the application.
static void onStartup (void)
 Startup QF callback.
static void onCleanup (void)
 Cleanup QF callback.
static void onIdle (void)
 QF idle callback (customized in BSPs for QF)
static void stop (void)
 Function invoked by the application layer to stop the QF application and return control to the OS/Kernel.
static void publish (QEvt const *e, void const *sender)
 Publish event to the framework.
static void tick (void const *const sender)
 Processes all armed time events at every clock tick.
static bool noTimeEvtsActive (void)
 Returns true if all time events are inactive and false any time event is active.
static char_t const Q_ROM
*Q_ROM_VAR 
getVersion (void)
 Returns the QF version.
static uint32_t getPoolMargin (uint8_t const poolId)
 This function returns the margin of the given event pool.
static uint32_t getQueueMargin (uint8_t const prio)
 This function returns the margin of the given event queue.
static QEvt * new_ (QEvtSize const evtSize, enum_t const sig)
 Internal QF implementation of the dynamic event allocator.
static void gc (QEvt const *e)
 Recycle a dynamic event.
static void remove_ (QActive const *const a)
 Remove the active object from the framework.
static void thread_ (QActive *act)
 Thread routine for executing an active object act.

Static Public Attributes

static QActiveactive_ []
 array of registered active objects

Friends

class QActive

Detailed Description

QF services.

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

Definition at line 605 of file qf.h.


Member Function Documentation

QP_BEGIN_ void QF::gc ( QEvt const *  e) [static]

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->attrQF__ attribute.) Next, the function decrements the reference counter of the event, 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. The pool-of-origin information is stored in the upper 2-MSBs of the e->attrQF__ attribute.)

Note:
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 CANNOT be performed for these events. In this case you need to call QF::gc() explicitly.

Definition at line 47 of file qf_gc.cpp.

References Q_ASSERT, QF_EPOOL_PUT_, QF_EVT_CONST_CAST_, QF_EVT_POOL_ID_(), QF_EVT_REF_CTR_(), QF_EVT_REF_CTR_DEC_(), QF_maxPool_, QF_pool_, QS_BEGIN_NOCRIT_, QS_END_NOCRIT_, QS_QF_GC, QS_QF_GC_ATTEMPT, QS_TIME_, QS_U8_, u8_0, and u8_1.

Referenced by publish(), QK_sched_(), QK_schedExt_(), and run().

uint32_t QF::getPoolMargin ( uint8_t const  poolId) [static]

This function returns the margin of the given event pool.

This function returns the margin of the given event pool poolId, where poolId is the ID of the pool initialized by the call to QF::poolInit(). The poolId of the first initialized pool is 1, the second 2, and so on.

The returned pool margin is the minimal number of free blocks encountered in the given pool since system startup.

Note:
Requesting the margin of an un-initialized pool raises an assertion in the QF.

Definition at line 73 of file qmp_get.cpp.

References Q_REQUIRE, QF_maxPool_, QF_pool_, and u8_1.

uint32_t QF::getQueueMargin ( uint8_t const  prio) [static]

This function returns the margin of the given event queue.

This function returns the margin of the given event queue of an active object with priority prio. (QF priorities start with 1 and go up to QF_MAX_ACTIVE.) The margin is the minimal number of free events encountered in the given queue since system startup.

Note:
QF::getQueueMargin() is available only when the native QF event queue implementation is used. Requesting the queue margin 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.)

Definition at line 93 of file qa_get_.cpp.

References Q_REQUIRE, and QF_MAX_ACTIVE.

char_t const Q_ROM *Q_ROM_VAR QF::getVersion ( void  ) [static]

Returns the QF version.

This function returns constant version string in the format x.y.zz, where x (one digit) is the major version, y (one digit) is the minor version, and zz (two digits) is the maintenance release version. An example of the version string is "3.1.03".

The following example illustrates the usage of this function:

printf("Quantum DPP\nQEP %s\nQF  %s, QF port %s\n"
       "Press ESC to quit...\n",
       QEP::getVersion(),                                       // QEP version
       QF::getVersion(),                                         // QF version
       QF::getPortVersion());                               // QF-port version

Definition at line 52 of file qf_act.cpp.

References QP_VERSION.

void QF::init ( void  ) [static]

QF initialization.

This function initializes QF and must be called exactly once before any other QF function.

Definition at line 61 of file qvanilla.cpp.

QP_BEGIN_ QEvt * QF::new_ ( QEvtSize const  evtSize,
enum_t const  sig 
) [static]

Internal QF implementation of the dynamic event allocator.

Note:
The application code should not call this function directly. Please use the macro #Q_NEW.

Definition at line 47 of file qf_new.cpp.

References Q_ASSERT, QF_EPOOL_EVENT_SIZE_, QF_EPOOL_GET_, QF_maxPool_, QF_pool_, QS_BEGIN_, QS_CRIT_STAT_, QS_END_, QS_QF_NEW, QS_TIME_, QSignal, u8_0, and u8_1.

bool QF::noTimeEvtsActive ( void  ) [static]

Returns true if all time events are inactive and false any time event is active.

Note:
This function should be called in critical section.

Definition at line 50 of file qte_arm.cpp.

static void QF::onCleanup ( void  ) [static]

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::init() and QF::stop()

Referenced by stop().

static void QF::onIdle ( void  ) [static]

QF idle callback (customized in BSPs for QF)

QF::onIdle() is called by the non-preemptive "Vanilla" scheduler built into QF when the framework detects that no events are available for active objects (the idle condition). This callback gives the application an opportunity to enter a power-saving CPU mode, or perform some other idle processing (such as Q-Spy output).

Note:
QF_onIdle() is invoked with interrupts DISABLED because the idle condition can be asynchronously changed at any time by an interrupt. QF_onIdle() MUST enable the interrupts internally, but not before putting the CPU into the low-power mode. (Ideally, enabling interrupts and low-power mode should happen atomically). At the very least, the function MUST enable interrupts, otherwise interrupts will remain disabled permanently.
QF::onIdle() is only used by the non-preemptive "Vanilla" scheduler in the "bare metal" QF port, and is NOT used in any other QF ports. When QF is combined with QK, the QK idle loop calls a different function QK::onIdle(), with different semantics than QF::onIdle(). When QF is combined with a 3rd-party RTOS or kernel, the idle processing mechanism of the RTOS or kernel is used instead of QF::onIdle().

Referenced by run().

static void QF::onStartup ( void  ) [static]

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.

Referenced by run().

void QF::poolInit ( void *const  poolSto,
uint32_t const  poolSize,
uint32_t const  evtSize 
) [static]

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. The arguments are as follows: poolSto is a pointer to the memory block for the events. poolSize is the size of the memory block in bytes. evtSize is the block-size of the pool in bytes, which determines the maximum size of events that can be allocated from the pool.

You might initialize one, two, and up to three event pools by making one, two, or three 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 used 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 class QMPool for more information.

Note:
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::getPoolMargin().
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 52 of file qf_pool.cpp.

References Q_DIM, Q_REQUIRE, QF_EPOOL_EVENT_SIZE_, QF_EPOOL_INIT_, QF_maxPool_, QF_pool_, u8_0, and u8_1.

void QF::psInit ( QSubscrList *const  subscrSto,
uint32_t const  maxSignal 
) [static]

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. The arguments are as follows: subscrSto is a pointer to the array of subscriber-lists. maxSignal is the dimension of this 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 mapping between the signals and subscirber-lists. The subscriber- lists are bitmasks of type QSubscrList, each bit in the bitmask corresponding to the unique priority of an active object. The size of the QSubscrList bitmask depends on the value of the QF_MAX_ACTIVE macro.

Note:
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:
QSubscrList

The following example shows the typical initialization sequence of QF:

// allocate storage for active objects, event queues, event pools,
// subscriber lists, and stacks.
static QEvent const *l_tableQueueSto[N_PHILO];
static QEvent const *l_philoQueueSto[N_PHILO][N_PHILO];
static QSubscrList   l_subscrSto[MAX_PUB_SIG];

static union SmallEvents {
    void *min_size;
    TableEvt te;
    // other event types to go into this pool
} l_smlPoolSto[2*N_PHILO];                 // storage for the small event pool

//............................................................................
int main(int argc, char *argv[]) {

    BSP_init(argc, argv);                               // initialize the BSP

    QF::init();       // initialize the framework and the underlying RT kernel

    QF::psInit(l_subscrSto, Q_DIM(l_subscrSto));     // init publish-subscribe

                                                  // initialize event pools...
    QF::poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0]));

                                                // start the active objects...
    uint8_t n;
    for (n = 0; n < N_PHILO; ++n) {
        AO_Philo[n]->start((uint8_t)(n + 1),
                           l_philoQueueSto[n], Q_DIM(l_philoQueueSto[n]),
                           (void *)0, 0, (QEvent *)0);
    }
    AO_Table->start((uint8_t)(N_PHILO + 1),
                    l_tableQueueSto, Q_DIM(l_tableQueueSto),
                    (void *)0, 0, (QEvent *)0);

    QF::run();                                       // run the QF application

    return 0;
}

Definition at line 49 of file qf_psini.cpp.

References QF_maxSignal_.

QP_BEGIN_ void QF::publish ( QEvt const *  e,
void const *  sender 
) [static]

Publish event to the framework.

This function posts (using the FIFO policy) the event e it to ALL active object that have subscribed to the signal e->sig. This function is designed to be callable from any part of the system, including ISRs, device drivers, and active objects.

In the general case, event publishing requires multi-casting the event to multiple subscribers. This happens in the caller's thread with the scheduler locked to prevent preemption during the multicasting process. (Please note that the interrupts are enabled.)

Definition at line 50 of file qf_pspub.cpp.

References active_, gc(), Q_ASSERT, Q_REQUIRE, QF_EVT_POOL_ID_(), QF_EVT_REF_CTR_(), QF_EVT_REF_CTR_INC_(), QF_invPwr2Lkup, QF_maxSignal_, QF_PTR_AT_, QF_SUBSCR_LIST_SIZE, QF_subscrList_, QS_BEGIN_NOCRIT_, QS_END_NOCRIT_, QS_OBJ_, QS_QF_PUBLISH, QS_TIME_, QS_U8_, and u8_0.

void QF::remove_ ( QActive const *const  a) [static]

Remove the active object from the framework.

This function should not be called by the application directly, only inside the QF port. The priority level occupied by the active object is freed-up and can be reused for another active object.

The active object that is removed from the framework can no longer participate in the publish-subscribe event exchange.

Note:
This function raises an assertion if the priority of the active object exceeds the maximum value QF_MAX_ACTIVE or is not used.

Definition at line 86 of file qf_act.cpp.

References active_, QS::aoObj_, Q_REQUIRE, QF_MAX_ACTIVE, QS_BEGIN_NOCRIT_, QS_END_NOCRIT_, QS_OBJ_, QS_QF_ACTIVE_REMOVE, QS_TIME_, QS_U8_, and u8_0.

Referenced by QActive::stop().

int16_t QF::run ( void  ) [static]

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(). Also, QF::start() call must precede the transfer of control to QF::run(), but some QF ports might call QF::start() from QF::run(). QF::run() typically never returns to the caller, but when it does, it returns the error code (0 for success)

Note:
This function is strongly platform-dependent and is not implemented in the QF, but either in the QF port or in the Board Support Package (BSP) for the given application. All QF ports must implement QF::run().
When the Quantum Kernel (QK) is used as the underlying real-time kernel for the QF, all platfrom dependencies are handled in the QK, so no porting of QF is necessary. In other words, you only need to recompile the QF platform-independent code with the compiler for your platform, but you don't need to provide any platform-specific implementation (so, no qf_port.cpp file is necessary). Moreover, QK implements the function QF::run() in a platform-independent way, in the modile qk.cpp.

Definition at line 70 of file qvanilla.cpp.

References active_, QPSet64::findMax(), gc(), QPSet64::notEmpty(), onIdle(), onStartup(), QF_currPrio_, QF_INT_DISABLE, QF_INT_ENABLE, and QF_readySet_.

void QF::stop ( void  ) [static]

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 funcition 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.

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::stop() at all, because many embedded application don't have anything to exit to.

See also:
QF::stop() and QF::onCleanup()

Definition at line 65 of file qvanilla.cpp.

References onCleanup().

static void QF::thread_ ( QActive act) [static]

Thread routine for executing an active object act.

This function is actually implemented internally by certain QF ports to be called by the active object thread routine.

QP_BEGIN_ void QF::tick ( void const *const  sender) [static]

Processes all armed time events at every clock tick.

This function must be called periodically from a time-tick ISR or from the highest-priority task so that QF can manage the timeout events.

Note:
The QF::tick() function is not reentrant meaning that it must run to completion before it is called again. Also, QF::tick() assumes that it never will get preempted by a task, which is always the case when it is called from an ISR or the highest-priority task.
See also:
QTimeEvt.

The following example illustrates the call to QF::tick():

// case 1: Interrupt Controller available,
// "unconditional interrupt unlocking" critical section policy
// (nesting of critical sections _not_ allowed)
//
interrupt void ISR_timer() {     // entered with interrupts locked in hardware
    QF_INT_UNLOCK(dummy);                                 // unlock interrupts

    QF::tick();                              //<-- call the QF tick processing

    QF_INT_LOCK(dummy);                               // lock 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();                              //<-- call the QF tick processing
}

Definition at line 49 of file qf_tick.cpp.

References Q_ASSERT, QF_EVT_REF_CTR_DEC_(), QF_timeEvtListHead_, QS_BEGIN_NOCRIT_, QS_END_NOCRIT_, QS_OBJ_, QS_QF_TICK, QS_QF_TIMEEVT_AUTO_DISARM, QS_QF_TIMEEVT_POST, QS_TIME_, QS::teObj_, and QS::tickCtr_.


Member Data Documentation

array of registered active objects

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

Definition at line 908 of file qf.h.

Referenced by publish(), QK_sched_(), QK_schedExt_(), remove_(), run(), QActive::subscribe(), QActive::unsubscribe(), and QActive::unsubscribeAll().


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