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 Q_ROM_BYTE(rom_var_)   (rom_var_)
 Macro to access a byte allocated in ROM.
#define Q_ROM_PTR(rom_var_)   (rom_var_)
 Macro to access a pointer allocated in ROM.
#define QActive_ctor(me_, initial_)   QHsm_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_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.
void QF_onIdle (void)
 QF idle callback (customized in BSPs for QF).

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 Q_ROM_BYTE ( rom_var_   )     (rom_var_)

Macro to access a byte allocated in ROM.

Some compilers for Harvard-architecture MCUs, such as gcc for AVR, do not generate correct code for accessing data allocated in the program space (ROM). The workaround for such compilers is to explictly add assembly code to access each data element allocated in the program space. The macro Q_ROM_BYTE() retrieves a byte from the given ROM address.

The Q_ROM_BYTE() macro should be defined in the qpn_port.h header file for each compiler that cannot handle correctly data allocated in ROM (such as the gcc). If the macro is left undefined, the default definition simply returns the argument and lets the compiler synthesize the correct code.

Definition at line 71 of file qfn.h.

#define Q_ROM_PTR ( rom_var_   )     (rom_var_)

Macro to access a pointer allocated in ROM.

Some compilers for Harvard-architecture MCUs, such as gcc for AVR, do not generate correct code for accessing data allocated in the program space (ROM). The workaround for such compilers is to explictly add assembly code to access each data element allocated in the program space. The macro Q_ROM_PTR() retrieves an object-pointer from the given ROM address. Please note that the pointer can be pointing to the object in RAM or ROM.

The Q_ROM_PTR() macro should be defined in the qpn_port.h header file for each compiler that cannot handle correctly data allocated in ROM (such as the gcc). If the macro is left undefined, the default definition simply returns the argument and lets the compiler synthesize the correct code.

Definition at line 90 of file qfn.h.

#define QActive_ctor ( me_,
initial_   )     QHsm_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 182 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 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_onIdle ( void   ) 

QF idle callback (customized in BSPs for QF).

QF_onIdle() is called by the non-preemptive scheduler built into QF-nano when the QF-nano 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.

Note:
QF_onIdle() is invoked with interrupts LOCKED because the idle condition can be asynchronously changed at any time by an interrupt. QF_onIdle() MUST unlock the interrupts internally, but not before putting the CPU into the low-power mode. (Ideally, unlocking interrupts and low-power mode should happen atomically). At the very least, the function MUST unlock interrupts, otherwise interrups will be locked permanently.

QF_onIdle() is not used in the PREEMPTIVE configuration. When QK_PREEMPTIVE macro is defined, the preemptive kernel QK-nano is used instead of the non-preemptive QF-nano scheduler. QK-nano uses a different idle callback

See also:
QK_onIdle().

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


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