qfn.c File Reference

#include "qpn_port.h"

Go to the source code of this file.

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.

Variables

uint8_t volatile QF_readySet_
 Ready set of QF-nano.


Detailed Description

QF-nano implementation.

Definition in file qfn.c.


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 151 of file qfn.c.

References QF_INT_LOCK, 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 157 of file qfn.c.

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_PAR, Q_PARAM_SIZE, Q_ROM_BYTE, Q_ROM_PTR, Q_SIG, QActive_post(), QF_active, QF_INT_LOCK, QF_INT_UNLOCK, QF_readySet_, QK_schedule_(), and QActiveCB::queue.

Referenced by QActive_post().

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 83 of file qfn.c.

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

Referenced by QF_tick().

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 132 of file qfn.c.

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


Variable Documentation

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(), and QK_schedule_().


Generated on Sat Dec 27 22:01:46 2008 for QP-nano by  doxygen 1.5.4