|
QP/C
|
QF/C platform-independent public interface. More...
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 | QF_EVENT_SIZ_SIZE 2 |
| Default value of the macro configurable value in qf_port.h. | |
| #define | QF_MAX_EPOOL 3 |
| Default value of the macro configurable value in qf_port.h. | |
| #define | QACTIVE_POST(me_, e_, sender_) QActive_postFIFO((me_), (e_), (sender_)) |
| Invoke the direct event posting facility QActive_postFIFO(). This macro is the recommended way of posting events, because it provides the vital information for software tracing and avoids any overhead when the tracing is disabled. | |
| #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 | QF_TIMEEVT_CTR_SIZE 2 |
| macro to override the default QTimeEvtCtr size. Valid values 1, 2, or 4; default 2 | |
| #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 | QF_PUBLISH(e_, sender_) QF_publish((e_), (sender_)) |
| Invoke the event publishing facility QF_publish(). 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. | |
| #define | QF_TICK(sender_) QF_tick(sender_) |
| Invoke the system clock tick processing QF_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. | |
| #define | Q_NEW(evtT_, sig_) ((evtT_ *)QF_new_((QEventSize)sizeof(evtT_), (QSignal)(sig_))) |
| Allocate a dynamic event. | |
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, void const *sender) |
| 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, QEQueue *eq, QEvent const *e) |
| Defer an event to a given separate event queue. | |
| uint8_t | QActive_recall (QActive *me, QEQueue *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. | |
| QTimeEvtCtr | QTimeEvt_ctr (QTimeEvt const *me) |
| Get the current value of the down-counter of 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 (void) |
| QF idle callback (customized in BSPs for QF) | |
| void | QF_publish (QEvent const *e, void const *sender) |
| Publish event to the framework. | |
| void | QF_tick (void const *sender) |
| 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_t const Q_ROM *Q_ROM_VAR | QF_getVersion (void) |
| Returns the QF version. | |
| char_t 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.
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 QACTIVE_POST | ( | me_, | |
| e_, | |||
| sender_ | |||
| ) | QActive_postFIFO((me_), (e_), (sender_)) |
Invoke the direct event posting facility QActive_postFIFO(). This macro is the recommended way of posting events, because it provides the vital information for software tracing and avoids any overhead when the tracing is disabled.
This macro takes the last argument sender_, which is a pointer to the sender object. This argument is actually only used when QS software tracing is disabled (macro #Q_SPY is defined). When QS software tracing is not enabled, the macro calls QF_publish() without the sender_ argument, so the overhead of passing this extra argument is entirely avoided.
Definition at line 275 of file qf.h.
Referenced by QF_publish(), and QF_tick().
| #define QF_PUBLISH | ( | e_, | |
| sender_ | |||
| ) | QF_publish((e_), (sender_)) |
Invoke the event publishing facility QF_publish(). 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.
This macro takes the last argument sender_, which is a 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_ argument, so the overhead of passing this extra argument is entirely avoided.
Invoke the system clock tick processing QF_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.
This macro takes the argument sender_, which is a 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_tick() without any arguments, so the overhead of passing this extra argument is entirely avoided.
| #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); }
| void QActive_defer | ( | QActive * | me, |
| QEQueue * | eq, | ||
| QEvent const * | e | ||
| ) |
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.
Definition at line 40 of file qa_defer.c.
References QEQueue_postFIFO().
| QEvent const* QActive_get_ | ( | QActive * | me | ) |
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 QACTIVE_EQUEUE_ONEMPTY_, QACTIVE_EQUEUE_WAIT_, QF_EVT_POOL_ID_, QF_EVT_REF_CTR_, QF_PTR_AT_, QS_aoObj_, QS_BEGIN_NOCRIT_, QS_END_NOCRIT_, QS_EQC_, QS_OBJ_, QS_QF_ACTIVE_GET, QS_QF_ACTIVE_GET_LAST, QS_TIME_, QS_U8_, and QEvent::sig.
Referenced by QF_run(), QK_sched_(), and QK_schedExt_().
| void QActive_postFIFO | ( | QActive * | me, |
| QEvent const * | e, | ||
| void const * | sender | ||
| ) |
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 Philo 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 46 of file qa_fifo.c.
References QActive::eQueue, Q_ASSERT, QACTIVE_EQUEUE_SIGNAL_, QF_EVT_POOL_ID_, QF_EVT_REF_CTR_, QF_EVT_REF_CTR_INC_, QF_PTR_AT_, QS_aoObj_, QS_BEGIN_NOCRIT_, QS_END_NOCRIT_, QS_EQC_, QS_OBJ_, QS_QF_ACTIVE_POST_FIFO, QS_TIME_, QS_U8_, and QEvent::sig.
| 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.
Definition at line 43 of file qa_lifo.c.
References Q_ASSERT, QACTIVE_EQUEUE_SIGNAL_, QF_EVT_POOL_ID_, QF_EVT_REF_CTR_, QF_EVT_REF_CTR_INC_, QF_PTR_AT_, QS_aoObj_, QS_BEGIN_NOCRIT_, QS_END_NOCRIT_, QS_EQC_, QS_OBJ_, QS_QF_ACTIVE_POST_LIFO, QS_TIME_, and QS_U8_.
Referenced by QActive_recall().
| uint8_t QActive_recall | ( | QActive * | me, |
| QEQueue * | eq | ||
| ) |
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 1 (TRUE) if an event has been recalled. Otherwise the function returns 0.
An active object can use multiple event queues to defer events of different kinds.
Definition at line 45 of file qa_defer.c.
References Q_ASSERT, QActive_postLIFO(), QEQueue_get(), QF_EVT_POOL_ID_, QF_EVT_REF_CTR_, and QF_EVT_REF_CTR_DEC_.
| 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 88 of file qvanilla.c.
References QActive::eQueue, QActive::prio, Q_ASSERT, Q_REQUIRE, QEQueue_init(), QF_add_(), QF_MAX_ACTIVE, QS_FLUSH, and QActive::super.
| 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 105 of file qvanilla.c.
References QF_remove_().
| void QActive_subscribe | ( | QActive const * | me, |
| QSignal | sig | ||
| ) |
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 Q_REQUIRE, Q_USER_SIG, QF_active_, QF_div8Lkup, QF_MAX_ACTIVE, QF_maxSignal_, QF_PTR_AT_, QF_pwr2Lkup, QF_subscrList_, QS_aoObj_, QS_BEGIN_NOCRIT_, QS_END_NOCRIT_, QS_OBJ_, QS_QF_ACTIVE_SUBSCRIBE, and QS_TIME_.
| void QActive_unsubscribe | ( | QActive const * | me, |
| QSignal | sig | ||
| ) |
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 Q_REQUIRE, Q_USER_SIG, QF_active_, QF_div8Lkup, QF_invPwr2Lkup, QF_MAX_ACTIVE, QF_maxSignal_, QF_PTR_AT_, QF_subscrList_, QS_aoObj_, QS_BEGIN_NOCRIT_, QS_END_NOCRIT_, QS_OBJ_, QS_QF_ACTIVE_UNSUBSCRIBE, 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 Q_REQUIRE, Q_USER_SIG, QF_active_, QF_div8Lkup, QF_invPwr2Lkup, QF_MAX_ACTIVE, QF_maxSignal_, QF_PTR_AT_, QF_pwr2Lkup, QF_subscrList_, QS_aoObj_, QS_BEGIN_NOCRIT_, QS_END_NOCRIT_, QS_OBJ_, QS_QF_ACTIVE_UNSUBSCRIBE, and QS_TIME_.
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 58 of file qf_act.c.
References QActive::prio, Q_REQUIRE, QF_active_, QF_MAX_ACTIVE, QS_aoObj_, QS_BEGIN_NOCRIT_, QS_END_NOCRIT_, QS_OBJ_, QS_QF_ACTIVE_ADD, QS_TIME_, and QS_U8_.
Referenced by QActive_start().
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_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_, and QS_U8_.
Referenced by QF_publish(), QF_run(), QK_sched_(), and QK_schedExt_().
| uint32_t QF_getPoolMargin | ( | uint8_t | poolId | ) |
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_t 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".
| uint32_t QF_getQueueMargin | ( | uint8_t | prio | ) |
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 87 of file qa_get_.c.
References Q_REQUIRE, QF_active_, and QF_MAX_ACTIVE.
| char_t 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 45 of file qf_act.c.
References QP_VERSION.
Referenced by QK_getVersion().
| void QF_init | ( | void | ) |
QF initialization.
This function initializes QF and must be called exactly once before any other QF function.
Definition at line 48 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 Q_ASSERT, QF_EPOOL_EVENT_SIZE_, QF_EPOOL_GET_, QF_EVT_POOL_ID_, QF_EVT_REF_CTR_, QF_maxPool_, QF_pool_, QS_BEGIN_, QS_CRIT_STAT_, QS_END_, QS_QF_NEW, 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 | ( | void | ) |
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).
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_, QF_EPOOL_INIT_, QF_maxPool_, and QF_pool_.
| 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, |
| void const * | sender | ||
| ) |
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. 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 43 of file qf_pspub.c.
References QSubscrList::bits, Q_ASSERT, Q_DIM, Q_REQUIRE, QACTIVE_POST, QF_active_, QF_EVT_POOL_ID_, QF_EVT_REF_CTR_, QF_EVT_REF_CTR_INC_, QF_gc(), QF_invPwr2Lkup, QF_log2Lkup, QF_maxSignal_, QF_PTR_AT_, QF_subscrList_, QS_BEGIN_NOCRIT_, QS_END_NOCRIT_, QS_OBJ_, QS_QF_PUBLISH, QS_TIME_, QS_U8_, and QEvent::sig.
| 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 78 of file qf_act.c.
References QActive::prio, Q_REQUIRE, QF_active_, QF_MAX_ACTIVE, QS_aoObj_, QS_BEGIN_NOCRIT_, QS_END_NOCRIT_, QS_OBJ_, 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 57 of file qvanilla.c.
References QActive_get_(), QF_active_, QF_gc(), QF_INT_DISABLE, QF_INT_ENABLE, QF_onIdle(), QF_onStartup(), QK_onIdle(), 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 52 of file qvanilla.c.
References QF_onCleanup().
| void QF_tick | ( | void const * | sender | ) |
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.
Definition at line 43 of file qf_tick.c.
References QTimeEvt::act, QTimeEvt::ctr, QTimeEvt::interval, QTimeEvt::next, QTimeEvt::prev, QACTIVE_POST, QF_timeEvtListHead_, QS_BEGIN_NOCRIT_, QS_END_NOCRIT_, QS_OBJ_, QS_QF_TICK, QS_QF_TIMEEVT_AUTO_DISARM, QS_QF_TIMEEVT_POST, QS_teObj_, QS_tickCtr_, QS_TIME_, QEvent::sig, and QTimeEvt::super.
| void QTimeEvt_arm_ | ( | QTimeEvt * | me, |
| QActive * | act, | ||
| QTimeEvtCtr | nTicks | ||
| ) |
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, QF_timeEvtListHead_, QS_BEGIN_NOCRIT_, QS_END_NOCRIT_, QS_OBJ_, QS_QF_TIMEEVT_ARM, QS_teObj_, and QS_TIME_.
| void QTimeEvt_ctor | ( | QTimeEvt * | me, |
| QSignal | sig | ||
| ) |
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, Q_USER_SIG, and QF_EVT_POOL_ID_.
| QTimeEvtCtr QTimeEvt_ctr | ( | QTimeEvt const * | me | ) |
Get the current value of the down-counter of a time event.
If the time event is armed, the function returns the current value of the down-counter of the given time event. If the time event is not armed, the function returns 0.
/note The function is thread-safe.
Definition at line 37 of file qte_ctr.c.
References QTimeEvt::act, QTimeEvt::ctr, QTimeEvt::interval, QTimeEvt::prev, QS_BEGIN_NOCRIT_, QS_END_NOCRIT_, QS_OBJ_, QS_QF_TIMEEVT_CTR, QS_teObj_, and QS_TIME_.
| uint8_t QTimeEvt_disarm | ( | QTimeEvt * | me | ) |
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_NOCRIT_, QS_END_NOCRIT_, QS_OBJ_, QS_QF_TIMEEVT_DISARM, QS_QF_TIMEEVT_DISARM_ATTEMPT, QS_teObj_, and QS_TIME_.
| uint8_t QTimeEvt_rearm | ( | QTimeEvt * | me, |
| QTimeEvtCtr | nTicks | ||
| ) |
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_NOCRIT_, QS_END_NOCRIT_, QS_OBJ_, 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_sched_(), and QK_schedExt_().
| uint8_t const Q_ROM Q_ROM_VAR QF_div8Lkup[65] |
Lookup table for (n-1)/8.
Definition at line 77 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 57 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.7.6.1