QP/C  7.2.2
Real-Time Embedded Framework
Loading...
Searching...
No Matches
QActive Class Reference

Active object class (based on the QHsm implementation strategy) More...

#include "qf.h"

Inheritance diagram for QActive:
QHsm QActiveDummy QMActive QTicker QXThread

Public Member Functions

void QActive_subscribe (QActive const *const me, enum_t const sig)
 
void QActive_unsubscribe (QActive const *const me, enum_t const sig)
 
void QActive_unsubscribeAll (QActive const *const me)
 
void QActive_setAttr (QActive *const me, uint32_t attr1, void const *attr2)
 
- Public Member Functions inherited from QHsm
bool QHsm_isIn (QHsm *const me, QStateHandler const state)
 
QStateHandler QHsm_childState (QHsm *const me, QStateHandler const parent)
 

Static Public Member Functions

void QActive_psInit (QSubscrList *const subscrSto, enum_t const maxSignal)
 
- Static Public Member Functions inherited from QHsm
static QStateHandler QHsm_state (QHsm *const me)
 

Public Attributes

QHsm super
 

Protected Member Functions

void QActive_ctor (QActive *const me, QStateHandler const initial)
 
void QActive_stop (QActive *const me)
 
bool QActive_defer (QActive const *const me, QEQueue *const eq, QEvt const *const e)
 
bool QActive_recall (QActive *const me, QEQueue *const eq)
 
uint_fast16_t QActive_flushDeferred (QActive const *const me, QEQueue *const eq)
 
void QActive_register_ (QActive *const me)
 
void QActive_unregister_ (QActive *const me)
 
- Protected Member Functions inherited from QHsm
void QHsm_ctor (QHsm *const me, QStateHandler const initial)
 
QState QHsm_top (QHsm const *const me, QEvt const *const e)
 
void QHsm_init_ (QHsm *const me, void const *const e, uint_fast8_t const qs_id)
 
void QHsm_dispatch_ (QHsm *const me, QEvt const *const e, uint_fast8_t const qs_id)
 

Private Member Functions

void QActive_start_ (QActive *const me, QPrioSpec const prioSpec, QEvt const **const qSto, uint_fast16_t const qLen, void *const stkSto, uint_fast16_t const stkSize, void const *const par)
 
bool QActive_post_ (QActive *const me, QEvt const *const e, uint_fast16_t const margin, void const *const sender)
 
void QActive_postLIFO_ (QActive *const me, QEvt const *const e)
 
QEvt const * QActive_get_ (QActive *const me)
 

Static Private Member Functions

void QActive_publish_ (QEvt const *const e, void const *const sender, uint_fast8_t const qs_id)
 
void QActive_thread_ (QActive *act)
 

Private Attributes

QF_EQUEUE_TYPE eQueue
 
QF_OS_OBJECT_TYPE osObject
 
QF_THREAD_TYPE thread
 
uint8_t prio
 
uint8_t pthre
 
QActiveQActive_active_ [QF_MAX_ACTIVE+1U]
 
QSubscrListQActive_subscrList_
 
enum_t QActive_maxPubSignal_
 
QActiveQActive_registry_ [QF_MAX_ACTIVE+1U]
 

Detailed Description

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

QActive represents an active object that uses the QHsm-style implementation strategy for state machines. This strategy is tailored to manual coding, but it is also supported by the QM modeling tool. The resulting code is slower than in the QMsm-style implementation strategy.

Note
QActive is not intended to be instantiated directly, but rather serves as the abstract base class for derivation of active objects in the applications.
See also
QMActive
Usage
The following example illustrates how to derive an active object from QActive.
typedef struct {
QActive super; /* inherits QActive */
QTimeEvt timeEvt; /* to timeout the blinking */
} Blinky;
. . .
void Blinky_ctor(Blinky * const me) {
/* constructor of the superclass <--- */
QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial));
/* constructor(s) of the members */
QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U);
}
#define Q_STATE_CAST(handler_)
Definition: qep.h:1050
Active object class (based on the QHsm implementation strategy)
Definition: qf.h:372
QHsm super
Definition: qf.h:374
void QActive_ctor(QActive *const me, QStateHandler const initial)
Definition: qf_qact.c:103
Time Event class.
Definition: qf.h:1066

Definition at line 372 of file qf.h.

Member Function Documentation

◆ QActive_ctor()

void QActive_ctor ( QActive *const  me,
QStateHandler const  initial 
)
protected

QActive constructor (abstract base class)

Parameters
[in,out]mecurrent instance pointer (see oop)
[in]initialpointer to the top-most initial state-handler function in the derived active object
See also
QHsm_ctor()

Definition at line 103 of file qf_qact.c.

◆ QActive_start_()

void QActive_start_ ( QActive *const  me,
QPrioSpec const  prioSpec,
QEvt const **const  qSto,
uint_fast16_t const  qLen,
void *const  stkSto,
uint_fast16_t const  stkSize,
void const *const  par 
)
private

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

Starts execution of the AO and registers the AO with the framework.

Parameters
[in,out]mecurrent instance pointer (see oop)
[in]prioSpecpriority specification for the AO (See QPrioSpec)
[in]qStopointer to the storage for the ring buffer of the event queue
[in]qLenlength of the event queue [# QEvt* pointers]
[in]stkStopointer to the stack storage (might be NULL)
[in]stkSizestack size [bytes]
[in]parpointer to an extra parameter (might be NULL)
Usage
The following example shows starting an AO when a per-task stack is needed:
#include "qpc.h"
Q_DEFINE_THIS_FILE
int main() {
QF_init(); /* initialize the framework and the underlying RT kernel */
BSP_init(); /* initialize the Board Support Package */
. . .
/* instantiate and start the active objects~~~ */
Blinky_ctor();
static QEvt const *l_blinkyQSto[10]; /* Event queue storage for Blinky */
QACTIVE_START(AO_Blinky, /* AO pointer to start */
1U, /* unique QP priority of the AO */
l_blinkyQSto, /* storage for the AO's queue */
Q_DIM(l_blinkyQSto), /* lenght of the queue [entries] */
(void *)0, /* stack storage (not used in QK) */
0U, /* stack size [bytes] (not used in QK) */
(void *)0); /* initialization parameter (or 0) */
. . .
return QF_run(); /* run the QF application */
}
#define Q_DIM(array_)
Definition: qassert.h:424
#define QACTIVE_START(me_, prioSpec_, qSto_, qLen_, stkSto_, stkSize_, par_)
Definition: qf.h:1907
QP/C public interface including backwards-compatibility layer.
int_t QF_run(void)
Definition: qutest.c:190
void QF_init(void)
Definition: qutest.c:171
Event class.
Definition: qep.h:167

Definition at line 210 of file qutest.c.

◆ QActive_stop()

void QActive_stop ( QActive *const  me)
protected

Stops execution of an active object and removes it from the framework's supervision

Parameters
[in,out]mecurrent instance pointer (see oop)
Attention
QActive_stop() must be called only from the AO that is about to stop its execution. By that time, any pointers or references to the AO are considered invalid (dangling) and it becomes illegal for the rest of the application to post events to the AO.

Definition at line 232 of file qutest.c.

◆ QActive_post_()

bool QActive_post_ ( QActive *const  me,
QEvt const *const  e,
uint_fast16_t const  margin,
void const *const  sender 
)
private

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

Direct event posting is the simplest asynchronous communication method available in QF.

Parameters
[in,out]mecurrent instance pointer (see oop)
[in]epointer to the event to be posted
[in]marginnumber of required free slots in the queue after posting the event or QF_NO_MARGIN.
[in]senderpointer to a sender object (used in QS only)
Returns
'true' (success) if the posting succeeded (with the provided margin) and 'false' (failure) when the posting fails.
Precondition qf_actq:100
  • event pointer must be valid
Postcondition qf_actq:190
Attention
For margin == QF_NO_MARGIN, this function will assert internally if the event posting fails. In that case, it is unnecessary to check the retrun value from this function.
Note
This function might be implemented differently in various QP/C++ ports. The provided implementation assumes that the QEQueue class is used for the QActive event queue.
See also
QActive_postLIFO()
Usage
extern QActive * const AO_Table;
QState Philoso_hungry(Philo * const me, QEvt const * const e) {
QState status;
switch (e->sig) {
case Q_ENTRY_SIG: {
TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); /* dynamic alloc */
pe->philNum = me->num;
QACTIVE_POST(AO_Table, &pe->super, me); /* <--- */
status = Q_HANDLED();
break;
}
. . .
default: {
status = Q_SUPER(&QHsm_top);
break;
}
}
return status;
}
#define Q_HANDLED()
Definition: qep.h:1002
enum QStateRet QState
Definition: qep.h:248
@ Q_ENTRY_SIG
Definition: qep.h:318
#define Q_SUPER(super_)
Definition: qep.h:991
#define Q_NEW(evtT_, sig_,...)
Definition: qf.h:1790
#define QACTIVE_POST(me_, e_, sender_)
Definition: qf.h:1939
QSignal sig
Definition: qep.h:176
QState QHsm_top(QHsm const *const me, QEvt const *const e)
Definition: qep_hsm.c:183

◆ QActive_postLIFO_()

void QActive_postLIFO_ ( QActive *const  me,
QEvt const *const  e 
)
private

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

The LIFO policy should be used only for self-posting and with caution, because it alters order of events in the queue.

Parameters
[in,out]mecurrent instance pointer (see oop)
[in]epointer to the event to be posted
Precondition qf_actq:200
  • the queue must be able to accept the event (cannot overflow)
Note
This function might be implemented differently in various QP/C++ ports. The provided implementation assumes that the QEQueue class is used for the QActive event queue.
See also
QActive_post()

Definition at line 198 of file qf_actq.c.

◆ QActive_get_()

QEvt const * QActive_get_ ( QActive *const  me)
private

Get an event from the event queue of an active object

The behavior of this function depends on the kernel used in the QF port. For built-in kernels (Vanilla or QK) the function can be called only when the queue is not empty, so it doesn't block. For a blocking kernel/OS the function can block and wait for delivery of an event.

Parameters
[in,out]mecurrent instance pointer (see oop)
Returns
A pointer to the received event. The returned pointer is guaranteed to be valid (can't be NULL).
Note
This function might be implemented differently in various QP/C++ ports. The provided implementation assumes that the QEQueue class is used for the QActive event queue.

Definition at line 267 of file qf_actq.c.

◆ QActive_subscribe()

void QActive_subscribe ( QActive const *const  me,
enum_t const  sig 
)

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.

Parameters
[in,out]mecurrent instance pointer (see oop)
[in]sigevent signal to subscribe
Precondition qf_ps:300
  • signal must be in range of subscribe scignals
  • subscriber AO priority must be in range
  • the AO must be registered (started)

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

See also
QActive_publish_(), QActive_unsubscribe(), and QActive_unsubscribeAll()

Definition at line 170 of file qf_ps.c.

◆ QActive_unsubscribe()

void QActive_unsubscribe ( QActive const *const  me,
enum_t const  sig 
)

Unsubscribes 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.

Parameters
[in,out]mecurrent instance pointer (see oop)
[in]sigevent signal to unsubscribe
Precondition qf_ps:400
  • signal must be in range of subscribe scignals
  • subscriber AO priority must be in range
  • the AO must be registered (started)
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 raise an assertion.
See also
QActive_publish_(), QActive_subscribe(), and QActive_unsubscribeAll()

Definition at line 199 of file qf_ps.c.

◆ QActive_unsubscribeAll()

void QActive_unsubscribeAll ( QActive const *const  me)

Unsubscribes 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.

Parameters
[in,out]mecurrent instance pointer (see oop)
Precondition qf_ps:500
  • subscriber AO priority must be in range
  • the AO must be registered (started)
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
QActive_publish_(), QActive_subscribe(), and QActive_unsubscribe()

Definition at line 228 of file qf_ps.c.

◆ QActive_psInit()

void QActive_psInit ( QSubscrList *const  subscrSto,
enum_t const  maxSignal 
)
static

Publish event to all subscribers of a given signal e->sig

This function posts (using the FIFO policy) the event e to all active objects that have subscribed to the signal e->sig, which is called multicasting. The multicasting performed in this function is very efficient based on reference-counting inside the published event ("zero-copy" event multicasting). This function is designed to be callable from any part of the system, including ISRs, device drivers, and active objects.

Note
To avoid any unexpected re-ordering of events posted into AO queues, the event multicasting is performed with scheduler locked. However, the scheduler is locked only up to the priority level of the highest-priority subscriber, so any AOs of even higher priority, which did not subscribe to this event are not affected.

◆ QActive_publish_()

void QActive_publish_ ( QEvt const *const  e,
void const *const  sender,
uint_fast8_t const  qs_id 
)
staticprivate

Publish event to all subscribers of a given signal e->sig

This function posts (using the FIFO policy) the event e to all active objects that have subscribed to the signal e->sig, which is called multicasting. The multicasting performed in this function is very efficient based on reference-counting inside the published event ("zero-copy" event multicasting). This function is designed to be callable from any part of the system, including ISRs, device drivers, and active objects.

Precondition qf_ps:200
  • the published signal must be within the configured range
Note
To avoid any unexpected re-ordering of events posted into AO queues, the event multicasting is performed with scheduler locked. However, the scheduler is locked only up to the priority level of the highest-priority subscriber, so any AOs of even higher priority, which did not subscribe to this event are not affected.

Definition at line 92 of file qf_ps.c.

◆ QActive_defer()

bool QActive_defer ( QActive const *const  me,
QEQueue *const  eq,
QEvt const *const  e 
)
protected

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.

Parameters
[in]eqpointer to a "raw" thread-safe queue to recall an event from.
[in]epointer to the event to be deferred
Returns
'true' (success) when the event could be deferred and 'false' (failure) if event deferral failed due to overflowing the queue.

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

See also
QActive_recall(), QEQueue, QActive_flushDeferred()

◆ QActive_recall()

bool QActive_recall ( QActive *const  me,
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.

Parameters
[in]eqpointer to a "raw" thread-safe queue to recall an event from.
Returns
'true' if an event has been recalled and 'false' if not.
Note
An active object can use multiple event queues to defer events of different kinds.
See also
QActive_recall(), QActive_postLIFO_(), QEQueue

Definition at line 88 of file qf_defer.c.

◆ QActive_flushDeferred()

uint_fast16_t QActive_flushDeferred ( QActive const *const  me,
QEQueue *const  eq 
)
protected

Flush the specified deferred queue 'eq'

This function is part of the event deferral support. An active object can use this function to flush a given QF event queue. The function makes sure that the events are not leaked.

Parameters
[in]eqpointer to a "raw" thread-safe queue to flush.
Returns
the number of events actually flushed from the queue.
See also
QActive_defer(), QActive_recall(), QEQueue

Definition at line 147 of file qf_defer.c.

◆ QActive_setAttr()

void QActive_setAttr ( QActive *const  me,
uint32_t  attr1,
void const *  attr2 
)

Generic setting of additional attributes (useful in QP ports)

◆ QActive_thread_()

void QActive_thread_ ( QActive act)
staticprivate

Thread routine for executing an active object act

◆ QActive_register_()

void QActive_register_ ( QActive *const  me)
protected

Register this active object to be managed by the framework

This function adds a given active object to the active objects managed by the QF framework. It should not be called by the application directly, only through the function QActive::start().

Parameters
[in,out]mecurrent instance pointer (see oop)
Precondition qf_qact:100
  • the "QF-priority" of the AO must be in range (must be set before calling QActive_register_())
  • the "QF-priority" must not be already in use (unique priority)
  • the "QF-priority" must not exceed the "preemption-threshold"
Postcondition qf_qact:190
  • the preceding pre-thre must not exceed the preemption-threshold
  • the preemption-threshold must not exceed the next pre-thre
See also
QActive_unregister_()

Definition at line 131 of file qf_qact.c.

◆ QActive_unregister_()

void QActive_unregister_ ( QActive *const  me)
protected

Un-register the active object from the framework

This function un-registers a given active object from the active objects managed by the QF framework. It should not be called by the QP ports.

Parameters
[in]mepointer to the active object to remove from the framework.
Precondition qf_qact:200
  • the priority of the active object must not be zero and cannot exceed the maximum QF_MAX_ACTIVE
  • the priority of the AO must be already registered.
Note
The active object that is removed from the framework can no longer participate in any event exchange.
See also
QActive_register_()

Definition at line 174 of file qf_qact.c.

Member Data Documentation

◆ super

QHsm QActive::super

Definition at line 374 of file qf.h.

◆ eQueue

QF_EQUEUE_TYPE eQueue
private

OS-dependent event-queue type

The type of the queue depends on the underlying operating system or a kernel. Many kernels support "message queues" that can be adapted to deliver QF events to the active object. Alternatively, QF provides a native event queue implementation that can be used as well.

Note
The native QF event queue is configured by defining the macro QF_EQUEUE_TYPE as QEQueue.

Definition at line 392 of file qf.h.

◆ osObject

QF_OS_OBJECT_TYPE osObject
private

OS-dependent per-thread object

This data might be used in various ways, depending on the QF port. In some ports me->osObject is used to block the calling thread when the native QF queue is empty. In other QF ports the OS-dependent object might be used differently.

Definition at line 405 of file qf.h.

◆ thread

QF_THREAD_TYPE thread
private

OS-dependent representation of the thread of the active object

This data might be used in various ways, depending on the QF port. In some ports me->thread is used store the thread handle. In other ports me->thread can be a pointer to the Thread-Local-Storage (TLS).

Definition at line 417 of file qf.h.

◆ prio

uint8_t prio
private

QF-priority [1..QF_MAX_ACTIVE] of this AO.

See also
QPrioSpec

Definition at line 426 of file qf.h.

◆ pthre

uint8_t pthre
private

preemption-threshold [1..QF_MAX_ACTIVE] of this AO.

See also
QPrioSpec

Definition at line 432 of file qf.h.

◆ QActive_active_

QActive* QActive_active_[QF_MAX_ACTIVE+1U]
private

Internal array of registered active objects

Definition at line 910 of file qf.h.

◆ QActive_subscrList_

QSubscrList* QActive_subscrList_
private

pointer to the array of all subscriber AOs for a given event signal.

Definition at line 915 of file qf.h.

◆ QActive_maxPubSignal_

enum_t QActive_maxPubSignal_
private

The maximum published signal (the size of the subscrList_ array)

Definition at line 920 of file qf.h.

◆ QActive_registry_

QActive* QActive_registry_[QF_MAX_ACTIVE+1U]
private

Internal array of registered active objects

Definition at line 925 of file qf.h.


The documentation for this class was generated from the following files: