QF/C platform-independent public interface. More...
#include "qs_port.h"Go to the source code of this file.
Data Structures | |
| struct | QActive |
| Active Object structure. More... | |
| struct | QTimeEvt |
| Time Event structure. More... | |
| struct | QSubscrList |
| Subscriber-List structure. More... | |
Defines | |
| #define | QActive_ctor(me_, initial_) QF_ACTIVE_CTOR_(&(me_)->super, (initial_)) |
| protected "constructor" of an active object. Performs the first step of active object initialization by assigning the initial pseudostate to the currently active state of the state machine. | |
| #define | QTimeEvt_postIn(me_, act_, nTicks_) |
| Arm a one-shot time event for direct event posting. | |
| #define | QTimeEvt_postEvery(me_, act_, nTicks_) |
| Arm a periodic time event for direct event posting. | |
| #define | Q_NEW(evtT_, sig_) ((evtT_ *)QF_new_(sizeof(evtT_), (sig_))) |
| Allocate a dynamic event. | |
| #define | QS_EQC_(ctr_) QS_u8_(ctr_) |
| Internal QS macro to output an unformatted event queue counter data element. | |
Functions | |
| void | QActive_start (QActive *me, uint8_t prio, QEvent const *qSto[], uint32_t qLen, void *stkSto, uint32_t stkSize, QEvent const *ie) |
| Starts execution of an active object and registers the object with the framework. | |
| void | QActive_postFIFO (QActive *me, QEvent const *e) |
| Posts an event e directly to the event queue of the acitve object me using the First-In-First-Out (FIFO) policy. | |
| void | QActive_postLIFO (QActive *me, QEvent const *e) |
| Posts an event directly to the event queue of the active object me using the Last-In-First-Out (LIFO) policy. | |
| void | QActive_stop (QActive *me) |
| Stops execution of an active object and removes it from the framework's supervision. | |
| void | QActive_subscribe (QActive const *me, QSignal sig) |
| Subscribes for delivery of signal sig to the active object me. | |
| void | QActive_unsubscribe (QActive const *me, QSignal sig) |
| Un-subscribes from the delivery of signal sig to the active object me. | |
| void | QActive_unsubscribeAll (QActive const *me) |
| Un-subscribes from the delivery of all signals to the active object me. | |
| void | QActive_defer (QActive *me, struct QEQueueTag *eq, QEvent const *e) |
| Defer an event to a given separate event queue. | |
| QEvent const * | QActive_recall (QActive *me, struct QEQueueTag *eq) |
| Recall a deferred event from a given event queue. | |
| QEvent const * | QActive_get_ (QActive *me) |
| Get an event from the event queue of an active object. | |
| void | QTimeEvt_ctor (QTimeEvt *me, QSignal sig) |
| The "constructor" to initialize a Time Event. | |
| uint8_t | QTimeEvt_disarm (QTimeEvt *me) |
| Disarm a time event. | |
| uint8_t | QTimeEvt_rearm (QTimeEvt *me, QTimeEvtCtr nTicks) |
| Rearm a time event. | |
| void | QTimeEvt_arm_ (QTimeEvt *me, QActive *act, QTimeEvtCtr nTicks) |
| Arm a time event (internal function to be used through macros only). | |
| void | QF_init (void) |
| QF initialization. | |
| void | QF_psInit (QSubscrList *subscrSto, QSignal maxSignal) |
| Publish-subscribe initialization. | |
| void | QF_poolInit (void *poolSto, uint32_t poolSize, QEventSize evtSize) |
| Event pool initialization for dynamic allocation of events. | |
| void | QF_run (void) |
| Transfers control to QF to run the application. | |
| void | QF_stop (void) |
| Function invoked by the application layer to stop the QF application and return control to the OS/Kernel. | |
| void | QF_onStartup (void) |
| Startup QF callback. | |
| void | QF_onCleanup (void) |
| Cleanup QF callback. | |
| void | QF_onIdle (QF_INT_KEY_TYPE intLockKey) |
| QF idle callback (customized in BSPs for QF). | |
| void | QF_publish (QEvent const *e) |
| Publish event to the framework. | |
| void | QF_tick (void) |
| Processes all armed time events at every clock tick. | |
| void | QF_add_ (QActive *a) |
| Register an active object to be managed by the framework. | |
| void | QF_remove_ (QActive const *a) |
| Remove the active object from the framework. | |
| char const Q_ROM *Q_ROM_VAR | QF_getVersion (void) |
| Returns the QF version. | |
| char const Q_ROM *Q_ROM_VAR | QF_getPortVersion (void) |
| Returns the QF-port version. | |
| uint32_t | QF_getPoolMargin (uint8_t poolId) |
| This function returns the margin of the given event pool. | |
| uint32_t | QF_getQueueMargin (uint8_t prio) |
| This function returns the margin of the given event queue. | |
| QEvent * | QF_new_ (QEventSize evtSize, QSignal sig) |
| Internal QF implementation of the dynamic event allocator. | |
| void | QF_gc (QEvent const *e) |
| Recycle a dynamic event. | |
Variables | |
| uint8_t const Q_ROM Q_ROM_VAR | QF_log2Lkup [256] |
| Lookup table for (log2(n) + 1), where n is the index into the table. | |
| uint8_t const Q_ROM Q_ROM_VAR | QF_pwr2Lkup [65] |
| Lookup table for (1 << ((n-1) % 8)), where n is the index into the table. | |
| uint8_t const Q_ROM Q_ROM_VAR | QF_invPwr2Lkup [65] |
| Lookup table for ~(1 << ((n-1) % 8)), where n is the index into the table. | |
| uint8_t const Q_ROM Q_ROM_VAR | QF_div8Lkup [65] |
| Lookup table for (n-1)/8. | |
| QActive * | QF_active_ [] |
| array of registered active objects | |
QF/C platform-independent public interface.
This header file must be included directly or indirectly in all modules (*.c files) that use QF or QK.
Definition in file qf.h.
| #define Q_NEW | ( | evtT_, | |||
| sig_ | ) | ((evtT_ *)QF_new_(sizeof(evtT_), (sig_))) |
Allocate a dynamic event.
This macro returns an event pointer cast to the type evtT_. The event is initialized with the signal sig. Internally, the macro calls the internal QF function QF_new_(), which always returns a valid event pointer.
The following example illustrates dynamic allocation of an event:
extern QActive *AO_Table; QState Philosopher_hungry(Philosopher *me, QEvent const *e) { TableEvt *pe; switch (e->sig) { case Q_ENTRY_SIG: { pe = Q_NEW(TableEvt, HUNGRY_SIG); /* dynamically allocate event */ pe->philNum = me->num; QActive_postFIFO(AO_Table, (QEvent *)pe); /* direct posting */ return Q_HANDLED(); } . . . } return Q_SUPER(&QHsm_top); }
| #define QActive_ctor | ( | me_, | |||
| initial_ | ) | QF_ACTIVE_CTOR_(&(me_)->super, (initial_)) |
protected "constructor" of an active object. Performs the first step of active object initialization by assigning the initial pseudostate to the currently active state of the state machine.
void Philosopher_ctor(Philosopher *me) { QActive_ctor(&me->super, (QStateHandler)&Philosopher_initial); QTimeEvt_ctor(&me->timeEvt, TIMEOUT_SIG); }
The following example illustrates how to invoke QFsm_ctor() in the "constructor" of a derived state machine:
void QCalc_ctor(QCalc *me) { QHsm_ctor(&me->super, (QStateHandler)&QCalc_initial); }
| #define QS_EQC_ | ( | ctr_ | ) | QS_u8_(ctr_) |
Internal QS macro to output an unformatted event queue counter data element.
Definition at line 992 of file qf.h.
Referenced by QActive_get_(), QActive_postFIFO(), QActive_postLIFO(), QEQueue_get(), QEQueue_init(), QEQueue_postFIFO(), and QEQueue_postLIFO().
| #define QTimeEvt_postEvery | ( | me_, | |||
| act_, | |||||
| nTicks_ | ) |
do { \ (me_)->interval = (nTicks_); \ QTimeEvt_arm_((me_), (act_), (nTicks_)); \ } while (0)
Arm a periodic time event for direct event posting.
Arms a time event me_ to fire every nTicks_ clock ticks (periodic time event). The time event gets directly posted (using the FIFO policy) into the event queue of the active object act_.
After posting, the time event gets automatically re-armed to fire again in the specified nTicks_ clock ticks.
A periodic time event can be disarmed only by calling the QTimeEvt_disarm() function. After disarming, the time event can be reused for a one-shot or periodic timeout requests.
Also, a periodic time event can be re-armed to shorten or extend the current period by calling the QTimeEvt_rearm() function. After adjusting the current period, the periodic time event goes back timing out at the original rate.
| #define QTimeEvt_postIn | ( | me_, | |||
| act_, | |||||
| nTicks_ | ) |
do { \ (me_)->interval = (QTimeEvtCtr)0; \ QTimeEvt_arm_((me_), (act_), (nTicks_)); \ } while (0)
Arm a one-shot time event for direct event posting.
Arms a time event me_ to fire in nTicks_ clock ticks (one-shot time event). The time event gets directly posted (using the FIFO policy) into the event queue of the active object act_.
After posting, the time event gets automatically disarmed and can be reused for a one-shot or periodic timeout requests.
A one-shot time event can be disarmed at any time by calling the QTimeEvt_disarm() function. Also, a one-shot time event can be re-armed to fire in a different number of clock ticks by calling the QTimeEvt_rearm() function.
The following example shows how to arm a one-shot time event from a state machine of an active object:
QState Philosopher_eating(Philosopher *me, QEvent const *e) { TableEvt *pe; switch (e->sig) { case Q_ENTRY_SIG: { QTimeEvt_postIn(&me->timeEvt, (QActive *)me, EAT_TIME); return Q_HANDLED(); } case TIMEOUT_SIG: { return Q_TRAN(&Philosopher_thinking); } case Q_EXIT_SIG: { pe = Q_NEW(TableEvt, DONE_SIG); pe->philNum = me->num; QF_publish((QEvent *)pe); return Q_HANDLED(); } } return Q_SUPER(&QHsm_top); }
Defer an event to a given separate event queue.
This function is part of the event deferral support. An active object uses this function to defer an event e to the QF-supported native event queue eq. QF correctly accounts for another outstanding reference to the event and will not recycle the event at the end of the RTC step. Later, the active object might recall one event at a time from the event queue.
An active object can use multiple event queues to defer events of different kinds.
Get an event from the event queue of an active object.
This function is used internally by a QF port to extract events from the event queue of an active object. This function depends on the event queue implementation and is sometimes implemented in the QF port (qf_port.c file). Depending on the underlying OS or kernel, the function might block the calling thread when no events are available.
Definition at line 43 of file qa_get_.c.
References QEvent::dynamic_, QACTIVE_EQUEUE_ONEMPTY_, QACTIVE_EQUEUE_WAIT_, QS_aoObj_, QS_BEGIN_NOLOCK_, QS_END_NOLOCK_, QS_EQC_, QS_QF_ACTIVE_GET, QS_QF_ACTIVE_GET_LAST, QS_SIG_, QS_TIME_, QS_U8_, and QEvent::sig.
Referenced by QF_run(), QK_schedule_(), and QK_scheduleExt_().
Posts an event e directly to the event queue of the acitve object me using the First-In-First-Out (FIFO) policy.
Direct event posting is the simplest asynchronous communication method available in QF. The following example illustrates how the Philosopher active object posts directly the HUNGRY event to the Table active object.
extern QActive *AO_Table; QState Philosopher_hungry(Philosopher *me, QEvent const *e) { TableEvt *pe; switch (e->sig) { case Q_ENTRY_SIG: { pe = Q_NEW(TableEvt, HUNGRY_SIG); /* dynamically allocate event */ pe->philNum = me->num; QActive_postFIFO(AO_Table, (QEvent *)pe); /* direct posting */ return Q_HANDLED(); } . . . } return Q_SUPER(&QHsm_top); }
Definition at line 43 of file qa_fifo.c.
References Q_ASSERT, QACTIVE_EQUEUE_SIGNAL_, QS_aoObj_, QS_BEGIN_NOLOCK_, QS_END_NOLOCK_, QS_EQC_, QS_QF_ACTIVE_POST_FIFO, QS_SIG_, QS_TIME_, and QS_U8_.
Referenced by QF_publish(), and QF_tick().
Posts an event directly to the event queue of the active object me using the Last-In-First-Out (LIFO) policy.
Definition at line 43 of file qa_lifo.c.
References Q_ASSERT, QACTIVE_EQUEUE_SIGNAL_, QS_aoObj_, QS_BEGIN_NOLOCK_, QS_END_NOLOCK_, QS_EQC_, QS_QF_ACTIVE_POST_LIFO, QS_SIG_, QS_TIME_, and QS_U8_.
Recall a deferred event from a given event queue.
This function is part of the event deferral support. An active object uses this function to recall a deferred event from a given QF event queue. Recalling an event means that it is removed from the deferred event queue eq and posted (LIFO) to the event queue of the active object.
QActive_recall() returns the pointer to the recalled event to the caller. The function returns NULL if no event has been recalled.
An active object can use multiple event queues to defer events of different kinds.
| void QActive_start | ( | QActive * | me, | |
| uint8_t | prio, | |||
| QEvent const * | qSto[], | |||
| uint32_t | qLen, | |||
| void * | stkSto, | |||
| uint32_t | stkSize, | |||
| QEvent const * | ie | |||
| ) |
Starts execution of an active object and registers the object with the framework.
The function takes seven arguments. me is a pointer to the active object structure. prio is the priority of the active object. QF allows you to start up to 63 active objects, each one having a unique priority number between 1 and 63 inclusive, where higher numerical values correspond to higher priority (urgency) of the active object relative to the others. qSto[] and qLen arguments are the storage and size of the event queue used by this active object. stkSto and stkSize are the stack storage and size in bytes. Please note that a per-active object stack is used only when the underlying OS requies it. If the stack is not required, or the underlying OS allocates the stack internally, the stkSto should be NULL and/or stkSize should be 0. ie is an optional initialization event that can be used to pass additional startup data to the active object. (Pass NULL if your active object does not expect the initialization event).
The following example shows starting of the Philosopher object when a per-task stack is required:
static Philosopher l_philo[N]; /* N Philosopher active objects */ static QEvent const *l_philQueueSto[N][N];/* storage for Philo event queues */ static int l_philoStk[N][256]; /* stacks for the Philosopher active objects */ main() { . . . for (n = 0; n < N; ++n) { TableEvt ie; /* initialization event for the Philosopher HSM */ ie.philNum = n; Philosopher_ctor(&l_philo[n]); QActive_start((QActive *)&l_philo[n], /* Philosopher number n */ (uint8_t)(n*10 + 1), /* priority */ l_philoQueueSto[n], Q_DIM(l_philoQueueSto[n]),/*queue */ l_philoStk[n], sizeof(l_philoStk[n]),/*uC/OS-II stack */ (QEvent const *)&ie); /* initialization event */ } . . . }
Definition at line 97 of file qvanilla.c.
References QActive::eQueue, QActive::osObject, QActive::prio, Q_ASSERT, Q_REQUIRE, QEQueue_init(), QF_add_(), QF_MAX_ACTIVE, QS_FLUSH, QActive::super, and QActive::thread.
| void QActive_stop | ( | QActive * | me | ) |
Stops execution of an active object and removes it from the framework's supervision.
The preferred way of calling this function is from within the active object that needs to stop. In other words, an active object should stop itself rather than being stopped by some other entity. This policy works best, because only the active object itself "knows" when it has reached the appropriate state for the shutdown.
Definition at line 114 of file qvanilla.c.
References QF_remove_().
Subscribes for delivery of signal sig to the active object me.
This function is part of the Publish-Subscribe event delivery mechanism available in QF. Subscribing to an event means that the framework will start posting all published events with a given signal sig to the event queue of the active object me.
The following example shows how the Table active object subscribes to three signals in the initial transition:
QState Table_initial(Table *me, QEvent const *e) { uint8_t n; (void)e; /* suppress the compiler warning */ QActive_subscribe((QActive *)me, HUNGRY_SIG); /* subscribe to HUNGRY */ QActive_subscribe((QActive *)me, DONE_SIG); /*... to DONE */ QActive_subscribe((QActive *)me, TERMINATE_SIG); /*...and to TERMINATE */ for (n = 0; n < N; ++n) { me->fork[n] = FREE; me->isHungry[n] = 0; } return Q_TRAN(&Table_serving); }
Definition at line 40 of file qa_sub.c.
References QSubscrList::bits, Q_REQUIRE, Q_USER_SIG, QF_active_, QF_div8Lkup, QF_MAX_ACTIVE, QF_maxSignal_, QF_pwr2Lkup, QF_subscrList_, QS_aoObj_, QS_BEGIN_NOLOCK_, QS_END_NOLOCK_, QS_QF_ACTIVE_SUBSCRIBE, QS_SIG_, and QS_TIME_.
Un-subscribes from the delivery of signal sig to the active object me.
This function is part of the Publish-Subscribe event delivery mechanism available in QF. Un-subscribing from an event means that the framework will stop posting published events with a given signal sig to the event queue of the active object me.
Definition at line 40 of file qa_usub.c.
References QSubscrList::bits, Q_REQUIRE, Q_USER_SIG, QF_active_, QF_div8Lkup, QF_invPwr2Lkup, QF_MAX_ACTIVE, QF_maxSignal_, QF_subscrList_, QS_aoObj_, QS_BEGIN_NOLOCK_, QS_END_NOLOCK_, QS_QF_ACTIVE_UNSUBSCRIBE, QS_SIG_, and QS_TIME_.
| void QActive_unsubscribeAll | ( | QActive const * | me | ) |
Un-subscribes from the delivery of all signals to the active object me.
This function is part of the Publish-Subscribe event delivery mechanism available in QF. Un-subscribing from all events means that the framework will stop posting any published events to the event queue of the active object me.
Definition at line 40 of file qa_usuba.c.
References QSubscrList::bits, Q_REQUIRE, Q_USER_SIG, QF_active_, QF_div8Lkup, QF_invPwr2Lkup, QF_MAX_ACTIVE, QF_maxSignal_, QF_pwr2Lkup, QF_subscrList_, QS_aoObj_, QS_BEGIN_NOLOCK_, QS_END_NOLOCK_, QS_QF_ACTIVE_UNSUBSCRIBE, QS_SIG_, and QS_TIME_.
| void QF_add_ | ( | QActive * | a | ) |
Register an active object to be managed by the framework.
This function should not be called by the application directly, only through the function QActive_start(). The priority of the active object a should be set before calling this function.
Definition at line 59 of file qf_act.c.
References QActive::prio, Q_REQUIRE, QF_active_, QS_aoObj_, QS_BEGIN_NOLOCK_, QS_END_NOLOCK_, QS_QF_ACTIVE_ADD, QS_TIME_, and QS_U8_.
Referenced by QActive_start().
| void QF_gc | ( | QEvent 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->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.)
Definition at line 40 of file qf_gc.c.
References Q_ASSERT, QF_EPOOL_PUT_, QF_maxPool_, QF_pool_, QS_BEGIN_NOLOCK_, QS_END_NOLOCK_, QS_QF_GC, QS_QF_GC_ATTEMPT, QS_SIG_, QS_TIME_, and QS_U8_.
Referenced by QF_publish(), QF_run(), QK_schedule_(), and QK_scheduleExt_().
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.
Definition at line 65 of file qmp_get.c.
References Q_REQUIRE, QF_maxPool_, and QF_pool_.
| char const Q_ROM* Q_ROM_VAR QF_getPortVersion | ( | void | ) |
Returns the QF-port 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 QF-port version string is "1.1.03".
Definition at line 48 of file qvanilla.c.
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.
Definition at line 85 of file qa_get_.c.
References Q_REQUIRE, QF_active_, and QF_MAX_ACTIVE.
| char const Q_ROM* Q_ROM_VAR QF_getVersion | ( | void | ) |
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(), QF_getVersion(), QF_getPortVersion());
Definition at line 46 of file qf_act.c.
References QP_VERSION.
| void QF_init | ( | void | ) |
QF initialization.
This function initializes QF and must be called exactly once before any other QF function.
Definition at line 53 of file qvanilla.c.
References QK_init().
Internal QF implementation of the dynamic event allocator.
Definition at line 40 of file qf_new.c.
References QEvent::dynamic_, Q_ASSERT, QF_EPOOL_EVENT_SIZE_, QF_EPOOL_GET_, QF_maxPool_, QF_pool_, QS_BEGIN_, QS_END_, QS_QF_NEW, QS_SIG_, QS_TIME_, and QEvent::sig.
| 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.
Referenced by QF_stop().
| void QF_onIdle | ( | QF_INT_KEY_TYPE | intLockKey | ) |
QF idle callback (customized in BSPs for QF).
QF_onIdle() is called by the non-preemptive 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).
Referenced by QF_run().
| 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.
Referenced by QF_run().
| void QF_poolInit | ( | void * | poolSto, | |
| uint32_t | poolSize, | |||
| QEventSize | 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. 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 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.
Definition at line 44 of file qf_pool.c.
References Q_DIM, Q_REQUIRE, QF_EPOOL_EVENT_SIZE_, and QF_EPOOL_INIT_.
| void QF_psInit | ( | QSubscrList * | subscrSto, | |
| QSignal | 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. 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 subscriber-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.
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 SmallEvent { 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[]) { uint8_t n; Philo_ctor(); /* instantiate all Philosopher active objects */ Table_ctor(); /* instantiate the Table active object */ BSP_init(argc, argv); /* initialize the Board Support Package */ 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])); for (n = 0; n < N_PHILO; ++n) { /* start the active objects... */ QActive_start(AO_Philo[n], (uint8_t)(n + 1), l_philoQueueSto[n], Q_DIM(l_philoQueueSto[n]), (void *)0, 0, (QEvent *)0); } QActive_start(AO_Table, (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 42 of file qf_psini.c.
References QF_maxSignal_.
| void QF_publish | ( | QEvent const * | e | ) |
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 preemptions during the multi-casting process. (Please note that the interrupts are not locked.)
Definition at line 40 of file qf_pspub.c.
References QSubscrList::bits, Q_ASSERT, Q_DIM, Q_REQUIRE, QActive_postFIFO(), QF_active_, QF_gc(), QF_invPwr2Lkup, QF_log2Lkup, QF_maxSignal_, QF_subscrList_, QS_BEGIN_NOLOCK_, QS_END_NOLOCK_, QS_QF_PUBLISH, QS_SIG_, QS_TIME_, and QS_U8_.
| void QF_remove_ | ( | QActive const * | a | ) |
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.
Definition at line 79 of file qf_act.c.
References QActive::prio, Q_REQUIRE, QF_active_, QS_aoObj_, QS_BEGIN_NOLOCK_, QS_END_NOLOCK_, QS_QF_ACTIVE_REMOVE, QS_TIME_, and QS_U8_.
Referenced by QActive_stop().
| void 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(). 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.
Definition at line 62 of file qvanilla.c.
References QActive_get_(), QF_active_, QF_gc(), QF_onIdle(), QF_onStartup(), QK_INT_LOCK_, QK_INT_LOCK_KEY_, QK_INT_UNLOCK_, QK_onIdle(), QK_SCHEDULE_, QPSet64_findMax, QPSet64_notEmpty, QPSet8_findMax, QPSet8_notEmpty, and QActive::super.
| 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 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 applications don't have anything to exit to.
Definition at line 57 of file qvanilla.c.
References QF_onCleanup().
| void QF_tick | ( | void | ) |
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.
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(ignore); /* unlock interrupts */ QF_tick(); /*<-- call the QF tick processing */ QF_INT_LOCK(ignore); /* 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 40 of file qf_tick.c.
References QTimeEvt::act, QTimeEvt::ctr, QTimeEvt::interval, QTimeEvt::next, QTimeEvt::prev, QActive_postFIFO(), QF_timeEvtListHead_, QS_BEGIN_NOLOCK_, QS_END_NOLOCK_, QS_QF_TICK, QS_QF_TIMEEVT_AUTO_DISARM, QS_QF_TIMEEVT_POST, QS_SIG_, QS_teObj_, QS_tickCtr_, QS_TIME_, QEvent::sig, and QTimeEvt::super.
Arm a time event (internal function to be used through macros only).
Definition at line 43 of file qte_arm.c.
References QTimeEvt::prev, Q_REQUIRE, Q_USER_SIG, QS_BEGIN_NOLOCK_, QS_END_NOLOCK_, QS_QF_TIMEEVT_ARM, QS_teObj_, and QS_TIME_.
The "constructor" to initialize a Time Event.
You should call this function exactly once for every Time Event object BEFORE arming the Time Event. The most important action performed in this function is assigning a signal to the Time Event. You can reuse the Time Event any number of times, but you should not change the signal. This is because pointers to Time Events might still be held in event queues and changing signal could to hard-to-detect errors.
The following example shows the invocation of QTimeEvt_ctor() from the "constructor" of the Philosopher active object that owns the time event
void Philosopher_ctor(Philosopher *me) { QActive_ctor(&me->super, (QStateHandler)&Philosopher_initial); QTimeEvt_ctor(&me->timeEvt, TIMEOUT_SIG); }
Definition at line 40 of file qte_ctor.c.
References Q_REQUIRE, and Q_USER_SIG.
Disarm a time event.
The time event me gets disarmed and can be reused. The function returns 1 (TRUE) if the time event was truly disarmed, that is, it was running. The return of 0 (FALSE) means that the time event was not truly disarmed because it was not running. The FALSE return is only possible for one-shot time events that have been automatically disarmed upon expiration. In this case the FALSE return means that the time event has already been posted or published and should be expected in the active object's state machine.
Definition at line 38 of file qte_darm.c.
References QTimeEvt::act, QTimeEvt::ctr, QTimeEvt::interval, QTimeEvt::next, QTimeEvt::prev, QF_timeEvtListHead_, QS_BEGIN_NOLOCK_, QS_END_NOLOCK_, QS_QF_TIMEEVT_DISARM, QS_QF_TIMEEVT_DISARM_ATTEMPT, QS_teObj_, and QS_TIME_.
Rearm a time event.
The time event me gets rearmed with a new number of clock ticks nTicks. This facility can be used to prevent a one-shot time event from expiring (e.g., a watchdog time event), or to adjusts the current period of a periodic time event. Rearming a periodic timer leaves the interval unchanged and is a convenient method to adjust the phasing of the periodic time event.
The function returns 1 (TRUE) if the time event was running as it was re-armed. The return of 0 (FALSE) means that the time event was not truly rearmed because it was not running. The FALSE return is only possible for one-shot time events that have been automatically disarmed upon expiration. In this case the FALSE return means that the time event has already been posted or published and should be expected in the active object's state machine.
Definition at line 40 of file qte_rarm.c.
References QTimeEvt::prev, Q_REQUIRE, Q_USER_SIG, QF_timeEvtListHead_, QS_BEGIN_NOLOCK_, QS_END_NOLOCK_, QS_QF_TIMEEVT_REARM, QS_teObj_, QS_TIME_, and QS_U8_.
array of registered active objects
Definition at line 41 of file qf_act.c.
Referenced by QActive_subscribe(), QActive_unsubscribe(), QActive_unsubscribeAll(), QF_add_(), QF_getQueueMargin(), QF_publish(), QF_remove_(), QF_run(), QK_schedule_(), and QK_scheduleExt_().
| uint8_t const Q_ROM Q_ROM_VAR QF_div8Lkup[65] |
Lookup table for (n-1)/8.
Definition at line 61 of file qf_pwr2.c.
Referenced by QActive_subscribe(), QActive_unsubscribe(), and QActive_unsubscribeAll().
| uint8_t const Q_ROM Q_ROM_VAR QF_invPwr2Lkup[65] |
Lookup table for ~(1 << ((n-1) % 8)), where n is the index into the table.
Definition at line 49 of file qf_pwr2.c.
Referenced by QActive_unsubscribe(), QActive_unsubscribeAll(), and QF_publish().
| uint8_t const Q_ROM Q_ROM_VAR QF_log2Lkup[256] |
Lookup table for (log2(n) + 1), where n is the index into the table.
This lookup delivers the 1-based number of the most significant 1-bit of a byte.
Definition at line 37 of file qf_log2.c.
Referenced by QF_publish().
| uint8_t const Q_ROM Q_ROM_VAR QF_pwr2Lkup[65] |
Lookup table for (1 << ((n-1) % 8)), where n is the index into the table.
Definition at line 37 of file qf_pwr2.c.
Referenced by QActive_subscribe(), and QActive_unsubscribeAll().
1.6.2