QP 状态机学习笔记3(QActive结构体)

/****************************************************************************/
/*! Active Object (based on ::QHsm implementation) */
/**
* @description
* Active objects in QP are encapsulated state machines (each embedding an
* event queue and a thread) 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.
* @n@n
* ::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.
*
* @usage
* The following example illustrates how to derive an active object from
* ::QActive. Please note that the ::QActive member @c super is defined as the
* __first__ member of the derived struct (see @ref oop).
* @include qf_qactive.c
*/
typedef struct QActive {
    QHsm super; /*!< inherits ::QHsm */

#ifdef QF_EQUEUE_TYPE
    /*! OS-dependent event-queue type. */
    /**
    * @description
    * 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.
    */
    QF_EQUEUE_TYPE eQueue;
#endif

#ifdef QF_OS_OBJECT_TYPE
    /*! OS-dependent per-thread object. */
    /**
    * @description
    * This data might be used in various ways, depending on the QF port.
    * In some ports 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.
    */
    QF_OS_OBJECT_TYPE osObject;
#endif

#ifdef QF_THREAD_TYPE
    /*! OS-dependent representation of the thread of the active object. */
    /**
    * @description
    * This data might be used in various ways, depending on the QF port.
    * In some ports thread is used to store the thread handle. In other
    * ports thread can be the pointer to the Thread-Local-Storage (TLS).
    */
    QF_THREAD_TYPE thread;
#endif

    /*! QF priority (1..#QF_MAX_ACTIVE) of this active object. */
    uint_fast8_t prio;

#ifdef qxk_h  /* QXK kernel used? */
    /*! QF start priority (1..#QF_MAX_ACTIVE) of this active object. */
    uint_fast8_t startPrio;
#endif

} QActive;

里面有一个事件队列EQUEUE

/****************************************************************************/
/*! Native QF Event Queue */
/**
* @description
* This class describes the native QF event queue, which can be used as
* the event queue for active objects, or as a simple "raw" event queue for
* thread-safe event passing among non-framework entities, such as ISRs,
* device drivers, or other third-party components.@n
* @n
* The native QF event queue is configured by defining the macro
* #QF_EQUEUE_TYPE as ::QEQueue in the specific QF port header file.@n
* @n
* The ::QEQueue structure contains only data members for managing an event
* queue, but does not contain the storage for the queue buffer, which must
* be provided externally during the queue initialization.@n
* @n
* The event queue can store only event pointers, not the whole events. The
* internal implementation uses the standard ring-buffer plus one external
* location that optimizes the queue operation for the most frequent case
* of empty queue.@n
* @n
* The ::QEQueue structure is used with two sets of functions. One set is for
* the active object event queue, which might need to block the active object
* task when the event queue is empty and might need to unblock it when
* events are posted to the queue. The interface for the native active object
* event queue consists of the following functions: QActive_post(),
* QActive_postLIFO(), and QActive_get_(). Additionally the function
* QEQueue_init() is used to initialize the queue.@n
* @n
* The other set of functions, uses ::QEQueue as a simple "raw" event
* queue to pass events between entities other than active objects, such as
* ISRs. The "raw" event queue is not capable of blocking on the get()
* operation, but is still thread-safe because it uses QF critical section
* to protect its integrity. The interface for the "raw" thread-safe queue
* consists of the following functions: QEQueue_post(),
* QEQueue_postLIFO(), and QEQueue_get(). Additionally the function
* QEQueue_init() is used to initialize the queue.
*
* @note Most event queue operations (both the active object queues and
* the "raw" queues) internally use  the QF critical section. You should be
* careful not to invoke those operations from other critical sections when
* nesting of critical sections is not supported.
*
* @sa ::QEQueue for the description of the data members
*/
typedef struct QEQueue {
    /*! pointer to event at the front of the queue. */
    /**
    * @description
    * All incoming and outgoing events pass through the frontEvt location.
    * When the queue is empty (which is most of the time), the extra
    * frontEvt location allows to bypass the ring buffer altogether,
    * greatly optimizing the performance of the queue. Only bursts of events
    * engage the ring buffer.
    *
    * @note The additional role of this attribute is to indicate the empty
    * status of the queue. The queue is empty when frontEvt is NULL.
    */
    QEvt const * volatile frontEvt;

    /*! pointer to the start of the ring buffer. */
    QEvt const **ring;

    /*! offset of the end of the ring buffer from the start of the buffer. */
    QEQueueCtr end;

    /*! offset to where next event will be inserted into the buffer. */
    QEQueueCtr volatile head;

    /*! offset of where next event will be extracted from the buffer. */
    QEQueueCtr volatile tail;

    /*! number of free events in the ring buffer. */
    QEQueueCtr volatile nFree;

    /*! minimum number of free events ever in the ring buffer. */
    /**
    * @description
    * this attribute remembers the low-watermark of the ring buffer,
    * which provides a valuable information for sizing event queues.
    * @sa QF_getQueueMargin().
    */
    QEQueueCtr nMin;
} QEQueue;

QEQueue


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值