qfn.h File Reference

Public QF-nano interface. More...

Go to the source code of this file.

Data Structures

struct  QActive
 Active Object struct. More...
struct  QActiveCB
 QActive Control Block. More...

Defines

#define QActive_ctor(me_, initial_)   QFsm_ctor(&(me_)->super, initial_)
 Active object constructor.

Typedefs

typedef uint16_t QTimeEvtCtr
 type of the Time Event counter, which determines the dynamic range of the time delays measured in clock ticks.

Functions

void QActive_post (QActive *me, QSignal sig, QParam par)
 Posts an event e directly to the event queue of the acitve object prio using the First-In-First-Out (FIFO) policy. This function briefly locks and unlocks interrupts to protect the queue integrity.
void QActive_postISR (QActive *me, QSignal sig, QParam par)
 Posts an event e directly to the event queue of the acitve object prio using the First-In-First-Out (FIFO) policy. This function does NOT lock/unlock interrupts when nesting of interrupts is not allowed. Also, this function never calls the QK-nano scheduler, because synchronous task preemptions are never necessary inside ISRs.
void QF_tick (void)
 Processes all armed time events at every clock tick.
void QActive_arm (QActive *me, QTimeEvtCtr tout)
 Arm the QP-nano one-shot time event. Since the tick counter is a multi-byte variable in this case, the operation must be performed inside a critical section.
void QActive_disarm (QActive *me)
 Disarm a time event. Since the tick counter is a multi-byte variable in this case, the operation must be performed inside a critical section.
void QF_init (void)
 QF-nano initialization.
void QF_stop (void)
 QF-nano termination.
void QF_onStartup (void)
 Startup QF-nano callback.
void QF_run (void)
 Transfers control to QF to run the application.

Variables

QActiveCB const Q_ROM Q_ROM_VAR QF_active []
uint8_t volatile QF_readySet_
 Ready set of QF-nano.

Detailed Description

Public QF-nano interface.

This header file must be included in all modules that use QP-nano. Typically, this header file is included indirectly through the header file qpn_port.h.

Definition in file qfn.h.


Define Documentation

#define QActive_ctor ( me_,
initial_   )     QFsm_ctor(&(me_)->super, initial_)

Active object constructor.

me pointer the active object structure derived from QActive. initial is the pointer to the initial state of the active object.

Note:
Must be called exactly ONCE for each active object in the application before calling QF_run().

Definition at line 186 of file qfn.h.


Typedef Documentation

typedef uint16_t QTimeEvtCtr

type of the Time Event counter, which determines the dynamic range of the time delays measured in clock ticks.

This typedef is configurable via the preprocessor switch QF_TIMEEVT_CTR_SIZE. The other possible values of this type are as follows:
none when (QF_TIMEEVT_CTR_SIZE not defined or == 0),
uint8_t when (QF_TIMEEVT_CTR_SIZE == 1);
uint16_t when (QF_TIMEEVT_CTR_SIZE == 2); and
uint32_t when (QF_TIMEEVT_CTR_SIZE == 4).

Definition at line 114 of file qfn.h.


Function Documentation

void QActive_arm ( QActive me,
QTimeEvtCtr  tout 
)

Arm the QP-nano one-shot time event. Since the tick counter is a multi-byte variable in this case, the operation must be performed inside a critical section.

Arms the time event of the active object me to expire in tout clock ticks (one-shot time event). Upon the expiration, the time event posts the reserved signal Q_TIMEOUT_SIG directly into the event queue of the active object me.

After posting, the time event gets automatically disarmed.

The time event can be disarmed (stoped) at any time by calling the QActive_disarm() function. Also, a one-shot time event can be re-armed to fire in a different number of clock ticks by calling QActive_arm() again.

The following example shows how to arm a one-shot time event from a state machine of an active object:

QState Pelican_carsGreen(Pelican *me) {
    switch (Q_SIG(me)) {
        case Q_ENTRY_SIG: {
            QActive_arm((QActive *)me, CARS_GREEN_MIN_TOUT);  /* arm timer */
            BSP_signalCars(CARS_GREEN);
            return Q_HANDLED();
        }
        case Q_INIT_SIG: {
            return Q_TRAN(&Pelican_carsGreenNoPed);
        }
    }
    return Q_SUPER(&Pelican_carsEnabled);
}

Definition at line 136 of file qfn.c.

References QF_INT_LOCK, QF_INT_UNLOCK, and QActive::tickCtr.

void QActive_disarm ( QActive me  ) 

Disarm a time event. Since the tick counter is a multi-byte variable in this case, the operation must be performed inside a critical section.

The time event of the active object me gets disarmed (stopped).

Note:
You should not assume that the Q_TIMEOUT_SIG event will not arrive after you disarm the time event. The timeout evetn could be already in the event queue.

Definition at line 142 of file qfn.c.

References QF_INT_LOCK, QF_INT_UNLOCK, and QActive::tickCtr.

void QActive_post ( QActive me,
QSignal  sig,
QParam  par 
)

Posts an event e directly to the event queue of the acitve object prio using the First-In-First-Out (FIFO) policy. This function briefly locks and unlocks interrupts to protect the queue integrity.

Direct event posting is the only asynchronous communication method available in QF-nano. The following example illustrates how the Ped active object posts directly the PED_WAITING event to the PELICAN crossing active object.

QState Ped_wait(Ped *me) {
    switch (Q_SIG(me)) {
        case Q_ENTRY_SIG: {
            BSP_showState(me->super.prio, "wait");
            me->retryCtr = N_ATTEMPTS;
            QActive_arm((QActive *)me, WAIT_TOUT);
            return Q_HANDLED();
        }
        case Q_TIMEOUT_SIG: {
            if ((--me->retryCtr) != 0) {
                QActive_arm((QActive *)me, WAIT_TOUT);
                QActive_post((QActive *)&AO_Pelican, PEDS_WAITING_SIG, 0);
            }
            else {
                return Q_TRAN(&Ped_off);
            }
            return Q_HANDLED();
        }
    }
    return Q_SUPER(&QHsm_top);
}

The producer of the event (Ped in this case) must only "know" a pointer recipient (&AO_Pelican), but the specific definition of the Pelican structure is not required.

Direct event posting should not be confused with direct event dispatching. In contrast to asynchronous event posting through event queues, direct event dispatching is synchronous. Direct event dispatching occurs when you call QHsm_dispatch(), or QFsm_dispatch() function.

Note:
This function is intended only to be used at the task level and shouln never be used inside ISRs.

Definition at line 48 of file qfn.c.

References QActiveCB::end, QActive::head, QActive::nUsed, QActive::prio, Q_ASSERT, Q_PARAM_SIZE, Q_ROM_BYTE, Q_ROM_PTR, QF_active, QF_INT_LOCK, QF_INT_UNLOCK, QF_readySet_, QK_schedule_(), and QActiveCB::queue.

void QActive_postISR ( QActive me,
QSignal  sig,
QParam  par 
)

Posts an event e directly to the event queue of the acitve object prio using the First-In-First-Out (FIFO) policy. This function does NOT lock/unlock interrupts when nesting of interrupts is not allowed. Also, this function never calls the QK-nano scheduler, because synchronous task preemptions are never necessary inside ISRs.

Note:
This function is intended only to be used inside ISRs and you should never use at the task level.
See also:
QF_post()

Definition at line 76 of file qfn.c.

References QActiveCB::end, QActive::head, QActive::nUsed, QActive::prio, Q_ASSERT, Q_PARAM_SIZE, Q_ROM_BYTE, Q_ROM_PTR, QF_active, QF_INT_LOCK, QF_INT_UNLOCK, QF_readySet_, and QActiveCB::queue.

Referenced by QF_tick().

void QF_init ( void   ) 

QF-nano initialization.

This function initializes the internal QF variables as well as all registered active objects to zero. In the C startup code compliant with the C Standard this clearing of internal valiables is unnecessary, because all static variables are supposed to be cleared in the startup code. However in non-compliant implementations calling QF_init() can be very handy.

Note:
Function QF_init() is defined in the separate module qf_init.c, which needs to be included in the build only if the non-standard initialization is required.

Definition at line 38 of file qfn_init.c.

References QActive::head, QActive::nUsed, Q_ASSERT, Q_ROM_PTR, QF_active, QF_MAX_ACTIVE, QF_readySet_, QK_currPrio_, QActive::tail, and QActive::tickCtr.

void QF_onStartup ( void   ) 

Startup QF-nano 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.

See also:
QF initialization example for QActiveCB.

Referenced by QF_run().

void QF_run ( void   ) 

Transfers control to QF to run the application.

QF_run() implemetns the simple non-preemptive scheduler. QF_run() must be called from your startup code after you initialize the QF and define at least one active object control block in QF_active[].

Note:
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.c file is necessary). Moreover, QK implements the function QF_run() in a platform-independent way, in the modile qk.c.

Definition at line 55 of file qkn.c.

References QActive::prio, Q_ASSERT, Q_ROM_PTR, QF_active, QF_INT_LOCK, QF_INT_UNLOCK, QF_MAX_ACTIVE, QF_onStartup(), QFsm_init(), QHsm_init(), QK_onIdle(), and QK_SCHEDULE_.

void QF_stop ( void   ) 

QF-nano termination.

This function terminates QF and performs any necessary cleanup. In QF-nano this function is defined in the BSP. Many QF ports might not require implementing QF_stop() at all, because many embedded applications don't have anything to exit to.

void QF_tick ( void   ) 

Processes all armed time events at every clock tick.

Note:
This function can be only calle from the ISR-level. You must also guarantee that QF_tick() runs to completion before it is called again.

The following example illustrates the call to QF_tick():

/* the system time tick ISR for C8051 from Silicon Labs ....................*/
#pragma vector=0x2B
__interrupt void timer2_ISR(void) {
   TMR2CN &= ~(1 << 7);                      /* Clear Timer2 interrupt flag */
   QF_tick();                    /* handle all armed time events in QF-nano */
}

/* the system time tick ISR for MSP430 from TI (non-preemptive case) .......*/
#pragma vector = TIMERA0_VECTOR
__interrupt void timerA_ISR(void) {
    __low_power_mode_off_on_exit();
   QF_tick();                    /* handle all armed time events in QF-nano */
}

/* the system time tick ISR for MSP430 from TI (preemptive case QK-nano) ...*/
#pragma vector = TIMERA0_VECTOR
__interrupt void timerA_ISR(void) {
    QK_ISR_ENTRY();                /* inform QK-nano about entering the ISR */
    QF_tick();                   /* handle all armed time events in QF-nano */
    QK_ISR_EXIT();                  /* inform QK-nano about exiting the ISR */
}

Definition at line 118 of file qfn.c.

References Q_ROM_PTR, Q_TIMEOUT_SIG, QActive_postISR(), QF_active, QF_MAX_ACTIVE, and QActive::tickCtr.


Variable Documentation

QActiveCB const Q_ROM Q_ROM_VAR QF_active[]

active object control blocks

Referenced by QActive_post(), QActive_postISR(), QF_init(), QF_run(), QF_tick(), and QK_schedule_().

uint8_t volatile QF_readySet_

Ready set of QF-nano.

The QF-nano ready set keeps track of active objects that are ready to run. The ready set represents each active object as a bit, with the bits assigned according to priorities of the active objects. The bit is set if the corresponding active object is ready to run (i.e., has one or more events in its event queue) and zero if the event queue is empty. The QF-nano ready set is one byte-wide, which corresponds to 8 active objects maximum.

Definition at line 39 of file qfn.c.

Referenced by QActive_post(), QActive_postISR(), QF_init(), and QK_schedule_().


Generated by  doxygen 1.6.2