QP is an event-driven, RTOS-like, active object framework for microcontrollers, such as mbed. The QP framework provides thread-safe execution of active objects (concurrent state machines) and support both manual and automatic coding of UML statecharts in readable, production-quality C or C++. Automatic code generation of QP code is supported by the free QM modeling tool.

Dependents:   qp_hangman qp_dpp qp_blinky

Embed: (wiki syntax)

« Back to documentation index

QActive Class Reference

Base class for derivation of application-level active object classes. More...

#include <qp.h>

Public Member Functions

void start (uint8_t const prio, QEvt const *qSto[], uint32_t const qLen, void *const stkSto, uint32_t const stkSize, QEvt const *const ie=static_cast< QEvt * >(0))
 Starts execution of an active object and registers the object with the framework.
void postFIFO (QEvt const *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 unsubscribeAll (void) const
 Un-subscribes from the delivery of all signals to the active object.

Protected Member Functions

 QActive (QF_ACTIVE_STATE_ const initial)
 protected constructor
void postLIFO (QEvt const *const e)
 Posts an event directly to the event queue of the active object me using the Last-In-First-Out (LIFO) policy.
void stop (void)
 Stops execution of an active object and removes it from the framework's supervision.
void subscribe (enum_t const sig) const
 Subscribes for delivery of signal sig to the active object.
void unsubscribe (enum_t const sig) const
 Un-subscribes from the delivery of signal sig to the active object.
void defer (QEQueue *const eq, QEvt const *const e) const
 Defer an event to a given separate event queue.
bool recall (QEQueue *const eq)
 Recall a deferred event from a given event queue.

Friends

class QF
class QTimeEvt

Detailed Description

Base class for derivation of application-level active object classes.

QActive is the base class for derivation of active objects. Active objects in QF are encapsulated tasks (each embedding a state machine and an event queue) that communicate with one another asynchronously by sending and receiving events. Within an active object, events are processed sequentially in a run-to-completion (RTC) fashion, while QF encapsulates all the details of thread-safe event exchange and queuing.

Note:
QActive is not intended to be instantiated directly, but rather serves as the base class for derivation of active objects in the application code.

The following example illustrates how to derive an active object from QActive.

See also:
QF_ACTIVE_SUPER_ defines the base class for QActive

Definition at line 1510 of file qp.h.


Constructor & Destructor Documentation

QActive ( QF_ACTIVE_STATE_ const   initial ) [protected]

protected constructor

Performs the first step of active object initialization by assigning the initial pseudostate to the currently active state of the state machine.

Note:
The constructor is protected to prevent direct instantiation of QActive objects. This class is intended only for derivation (abstract class).

Definition at line 1635 of file qp.h.


Member Function Documentation

QP_BEGIN_ void defer ( QEQueue *const   eq,
QEvt const *const   e 
) const [protected]

Defer an event to a given separate event queue.

QActive::defer() and QActive::recall() implementation.

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.

See also:
QActive::recall(), QEQueue

Definition at line 615 of file qp.cpp.

QP_END_ QP_BEGIN_ void postFIFO ( QEvt const *const   e )

Posts an event e directly to the event queue of the acitve object me using the First-In-First-Out (FIFO) policy.

QActive::postFIFO() implementation.

Direct event posting is the simplest asynchronous communication method available in QF. The following example illustrates how the Philosopher active obejct posts directly the HUNGRY event to the Table active object.

Note:
The producer of the event (Philosopher in this case) must only "know" the recipient (Table) by a generic (QActive *QDPP_table) pointer, but the specific definition of the Table class 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.
this source file is only included in the QF library when the native QF active object queue is used (instead of a message queue of an RTOS).

QActive::get_() and QF::getQueueMargin() definitions.

Note:
this source file is only included in the QF library when the native QF active object queue is used (instead of a message queue of an RTOS).

QActive::postLIFO() implementation.

Note:
this source file is only included in the QF library when the native QF active object queue is used (instead of a message queue of an RTOS).

QActive::subscribe() implementation.

QActive::unsubscribe() implementation.

QActive::unsubscribeAll() implementation.

QEQueue::postFIFO() implementation.

QEQueue::get() implementation.

QEQueue::init() implementation.

QEQueue::postLIFO() implementation.

QF::active_[], QF::getVersion(), and QF::add_()/QFremove_() implementation.

QF::gc() implementation.

QF_log2Lkup[] implementation.

QF::new_() implementation.

QF_pool_[] and QF_maxPool_ definition, QF::poolInit() implementation.

QF_subscrList_ and QF_maxSignal_ definition, QF::psInit() implementation.

QF::publish() implementation.

QF_pwr2Lkup[], QF_invPwr2Lkup[], and QF_div8Lkup[] definitions.

QF::tick() implementation.

QMPool::get() and QF::getPoolMargin() implementation.

QMPool::init() implementation.

QMPool::put() implementation.

QF_timeEvtListHead_ definition and QTimeEvt::arm_() implementation.

QTimeEvt::QTimeEvt() implementation.

QTimeEvt::ctr() implementation.

QTimeEvt::disarm() implementation.

QTimeEvt::rearm() implementation.

Internal (package scope) QK/C interface.

This is an internal macro for defining the critical section status type.

The purpose of this macro is to enable writing the same code for the case when critical sectgion status type is defined and when it is not. If the macro QF_CRIT_STAT_TYPE is defined, this internal macro provides the definition of the critical section status varaible. Otherwise this macro is empty.

See also:
QF_CRIT_STAT_TYPE

This is an internal macro for entering a critical section.

The purpose of this macro is to enable writing the same code for the case when critical sectgion status type is defined and when it is not. If the macro QF_CRIT_STAT_TYPE is defined, this internal macro invokes QF_CRIT_ENTRY passing the key variable as the parameter. Otherwise QF_CRIT_ENTRY is invoked with a dummy parameter.

See also:
QF_CRIT_ENTRY

This is an internal macro for exiting a cricial section.

The purpose of this macro is to enable writing the same code for the case when critical sectgion status type is defined and when it is not. If the macro QF_CRIT_STAT_TYPE is defined, this internal macro invokes QF_CRIT_EXIT passing the key variable as the parameter. Otherwise QF_CRIT_EXIT is invoked with a dummy parameter.

See also:
QF_CRIT_EXIT

< QK mutex priority ceiling

QK_readySet_, QK_currPrio_, and QK_intNest_ definitions and QK::getVersion(), QF::init(), QF::run(), QF::stop(), QActive::start(), QActive::stop() implementations.

QK_schedPrio_() and QK_sched_() implementation.

QK::mutexLock()/QKmutexUnlock() implementation.

"vanilla" cooperative kernel, QActive::start(), QActive::stop(), and QF::run() implementation.

< current task/interrupt priority

< interrupt nesting level

Internal (package scope) QS/C++ interface.

QS ring buffer counter and offset type

Internal QS macro to insert an un-escaped byte into the QS buffer

Internal QS macro to insert an escaped byte into the QS buffer

Internal QS macro to insert a escaped checksum byte into the QS buffer

Internal QS macro to access the QS ring buffer

Note:
The QS buffer is allocated by the user and is accessed through the pointer QS_ring_, which violates the MISRA-C 2004 Rule 17.4(req), pointer arithmetic other than array indexing. Encapsulating this violation in a macro allows to selectively suppress this specific deviation.

Frame character of the QS output protocol

Escape character of the QS output protocol

Escape modifier of the QS output protocol

The escaped byte is XOR-ed with the escape modifier before it is inserted into the QS buffer.

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 for the compilers 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 generate the correct code.

< pointer to the start of the ring buffer

< offset of the end of the ring buffer

< offset to where next byte will be inserted

< offset of where next event will be extracted

< number of bytes currently in the ring buffer

< the record sequence number

< the checksum of the current record

< the ring buffer is temporarily full

QS internal variables definitions and core QS functions implementations.

QS functions for internal use inside QP components

QS::getBlock() implementation

QS::getByte() implementation

QS::f32() implementation

QS::mem() implementation

QS::str() and QS::str_ROM() implementation

Definition at line 660 of file qp.cpp.

void postLIFO ( QEvt const *const   e ) [protected]

Posts an event directly to the event queue of the active object me using the Last-In-First-Out (LIFO) policy.

Note:
The LIFO policy should be used only for self-posting and with great caution because it alters order of events in the queue.
See also:
QActive::postFIFO()
bool recall ( QEQueue *const   eq ) [protected]

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 true if an event has been recalled. Otherwise the function returns false.

An active object can use multiple event queues to defer events of different kinds.

See also:
QActive::defer(), QEQueue, QActive::postLIFO()

Definition at line 619 of file qp.cpp.

void start ( uint8_t const   prio,
QEvt const *  qSto[],
uint32_t const   qLen,
void *const   stkSto,
uint32_t const   stkSize,
QEvt const *const   ie = static_cast< QEvt * >(0) 
)

Starts execution of an active object and registers the object with the framework.

The function takes six arguments. 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).

Note:
This function is strongly OS-dependent and must be defined in the QF port to a particular platform.

The following example shows starting of the Philosopher object when a per-task stack is required:

void stop ( void   ) [protected]

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 (that's why this function is protected). 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.

Note:
This function is strongly OS-dependent and should be defined in the QF port to a particular platform. This function is optional in embedded systems where active objects never need to be stopped.
void subscribe ( enum_t const   sig ) const [protected]

Subscribes for delivery of signal sig to the active object.

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.

The following example shows how the Table active object subscribes to three signals in the initial transition:

See also:
QF::publish(), QActive::unsubscribe(), and QActive::unsubscribeAll()
void unsubscribe ( enum_t const   sig ) const [protected]

Un-subscribes from the delivery of signal sig to the active object.

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.

Note:
Due to the latency of event queues, an active object should NOT assume that a given signal sig will never be dispatched to the state machine of the active object after un-subscribing from that signal. The event might be already in the queue, or just about to be posted and the un-subscribe operation will not flush such events.
Un-subscribing from a signal that has never been subscribed in the first place is considered an error and QF will rise an assertion.
See also:
QF::publish(), QActive::subscribe(), and QActive::unsubscribeAll()
void unsubscribeAll ( void   ) const

Un-subscribes from the delivery of all signals to the active object.

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.

Note:
Due to the latency of event queues, an active object should NOT assume that no events will ever be dispatched to the state machine of the active object after un-subscribing from all events. The events might be already in the queue, or just about to be posted and the un-subscribe operation will not flush such events. Also, the alternative event-delivery mechanisms, such as direct event posting or time events, can be still delivered to the event queue of the active object.
See also:
QF::publish(), QActive::subscribe(), and QActive::unsubscribe()