Exemplo n.º 1
0
void QActive_postFIFO(QActive *me, QEvent const *e) {
#else
void QActive_postFIFO(QActive *me, QEvent const *e, void const *sender) {
#endif

    QF_INT_LOCK_KEY_
    QF_INT_LOCK_();

    QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_POST_FIFO, QS_aoObj_, me)
        QS_TIME_();                                            /* timestamp */
        QS_OBJ_(sender);                               /* the sender object */
        QS_SIG_(e->sig);                         /* the signal of the event */
        QS_OBJ_(me);                      /* this active object (recipient) */
        QS_U8_(EVT_POOL_ID(e));                 /* the pool Id of the event */
        QS_U8_(EVT_REF_CTR(e));               /* the ref count of the event */
        QS_EQC_(0);                     /* number of free entries (unknown) */
        QS_EQC_(0);                 /* min number of free entries (unknown) */
    QS_END_NOLOCK_()

    if (EVT_POOL_ID(e) != (uint8_t)0) {              /* is it a pool event? */
        EVT_INC_REF_CTR(e);              /* increment the reference counter */
    }
    QF_INT_UNLOCK_();
    Q_ALLEGE(OSQPost((OS_EVENT *)me->eQueue, (void *)e) == OS_NO_ERR);
}
Exemplo n.º 2
0
/*..........................................................................*/
void QFsm_init_(QFsm * const me, QEvt const * const e) {
    QS_CRIT_STAT_

    Q_REQUIRE((me->vptr != (QMsmVtbl const *)0)    /* ctor must be executed */
              && (me->temp.fun != Q_STATE_CAST(0)) /* ctor must be executed */
              && (me->state.fun == Q_STATE_CAST(0)));/*init tran. NOT taken */

    QS_BEGIN_(QS_QEP_STATE_INIT, QS_priv_.smObjFilter, me)
        QS_OBJ_(me);                           /* this state machine object */
        QS_FUN_(Q_STATE_CAST(0));   /* source state (not defined for a FSM) */
        QS_FUN_(me->temp.fun);              /* the target of the transition */
    QS_END_()

                                 /* execute the top-most initial transition */
    Q_ALLEGE((*me->temp.fun)(me, e) == (QState)Q_RET_TRAN);/* must be taken */

    (void)QEP_TRIG_(me->temp.fun, Q_ENTRY_SIG);         /* enter the target */
    me->state.fun = me->temp.fun;            /* record the new active state */

    QS_BEGIN_(QS_QEP_INIT_TRAN, QS_priv_.smObjFilter, me)
        QS_TIME_();                                           /* time stamp */
        QS_OBJ_(me);                           /* this state machine object */
        QS_FUN_(me->state.fun);                     /* the new active state */
    QS_END_()
}
Exemplo n.º 3
0
/* NOTE: disarm a timer (no harm in disarming an already disarmed timer)    */
uint8_t QTimeEvt_disarm(QTimeEvt *me) {
    uint8_t wasArmed;
    QF_INT_LOCK_KEY_
    QF_INT_LOCK_();
    if (me->prev != (QTimeEvt *)0) {   /* is the time event actually armed? */
        wasArmed = (uint8_t)1;
        if (me == QF_timeEvtListHead_) {
            QF_timeEvtListHead_ = me->next;
        }
        else {
            if (me->next != (QTimeEvt *)0) {   /* not the last in the list? */
                me->next->prev = me->prev;
            }
            me->prev->next = me->next;
        }
        me->prev = (QTimeEvt *)0;        /* mark the time event as disarmed */

        QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_DISARM, QS_teObj_, me)
            QS_TIME_();                                        /* timestamp */
            QS_OBJ_(me);                          /* this time event object */
            QS_OBJ_(me->act);                          /* the active object */
            QS_TEC_(me->ctr);                        /* the number of ticks */
            QS_TEC_(me->interval);                          /* the interval */
        QS_END_NOLOCK_()
    }
Exemplo n.º 4
0
void QF_tick(void) {                                          /* see NOTE01 */
#else
void QF_tick(void const *sender) {
#endif

    QTimeEvt *t;
    QF_CRIT_STAT_

    QF_CRIT_ENTRY_();

    QS_BEGIN_NOCRIT_(QS_QF_TICK, (void *)0, (void *)0)
        QS_TEC_((QTimeEvtCtr)(++QS_tickCtr_));          /* the tick counter */
    QS_END_NOCRIT_()

    t = QF_timeEvtListHead_;
    while (t != (QTimeEvt *)0) {
        --t->ctr;
        if (t->ctr == (QTimeEvtCtr)0) {     /* is time evt about to expire? */
            if (t->interval != (QTimeEvtCtr)0) { /* is it periodic timeout? */
                t->ctr = t->interval;               /* rearm the time event */
            }
            else { /* one-shot timeout, disarm by removing it from the list */
                if (t == QF_timeEvtListHead_) {
                    QF_timeEvtListHead_ = t->next;
                }
                else {
                    if (t->next != (QTimeEvt *)0) {  /* not the last event? */
                        t->next->prev = t->prev;
                    }
                    t->prev->next = t->next;
                }
                t->prev = (QTimeEvt *)0;         /* mark the event disarmed */

                QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_AUTO_DISARM, QS_teObj_, t)
                    QS_OBJ_(t);                   /* this time event object */
                    QS_OBJ_(t->act);                   /* the active object */
                QS_END_NOCRIT_()
            }

            QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_POST, QS_teObj_, t)
                QS_TIME_();                                    /* timestamp */
                QS_OBJ_(t);                        /* the time event object */
                QS_SIG_(t->super.sig);         /* signal of this time event */
                QS_OBJ_(t->act);                       /* the active object */
            QS_END_NOCRIT_()

            QF_CRIT_EXIT_();/* exit crit. section before calling QF service */

                /* QACTIVE_POST() asserts internally if the queue overflows */
            QACTIVE_POST(t->act, &t->super, sender);
        }
        else {
            static uint8_t volatile dummy;
            QF_CRIT_EXIT_();
            dummy = (uint8_t)0;   /* execute a few instructions, see NOTE02 */
        }

        QF_CRIT_ENTRY_();  /* enter crit. section again to advance the link */
        t = t->next;
    }
Exemplo n.º 5
0
/*..........................................................................*/
void QTimeEvt_arm_(QTimeEvt *me, QActive *act, QTimeEvtCtr nTicks) {
    QF_CRIT_STAT_
    Q_REQUIRE((nTicks > (QTimeEvtCtr)0)  /* cannot arm a timer with 0 ticks */
              && (me->super.sig >= (QSignal)Q_USER_SIG)     /* valid signal */
              && (me->prev == (QTimeEvt *)0)   /* time evt must NOT be used */
              && (act != (QActive *)0));  /* active object must be provided */
    me->ctr = nTicks;
    me->prev = me;                                 /* mark the timer in use */
    me->act = act;

    QF_CRIT_ENTRY_();

    QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_ARM, QS_teObj_, me)
        QS_TIME_();                                            /* timestamp */
        QS_OBJ_(me);                              /* this time event object */
        QS_OBJ_(act);                                  /* the active object */
        QS_TEC_(nTicks);                             /* the number of ticks */
        QS_TEC_(me->interval);                              /* the interval */
    QS_END_NOCRIT_()

    me->next = QF_timeEvtListHead_;
    if (QF_timeEvtListHead_ != (QTimeEvt *)0) {
        QF_timeEvtListHead_->prev = me;
    }
    QF_timeEvtListHead_ = me;
    QF_CRIT_EXIT_();
}
Exemplo n.º 6
0
bool QActive_post_(QActive * const me, QEvt const * const e,
                   uint_fast16_t const margin, void const * const sender)
#endif /* Q_SPY */
{
    uint_fast16_t nFree;
    bool status;
    QF_CRIT_STAT_

    QF_CRIT_ENTRY_();
    nFree = (uint_fast16_t)(me->eQueue.maxMsg - me->eQueue.nofMsg);

    if (nFree > margin) {
        QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_FIFO, QS_priv_.aoObjFilter, me)
            QS_TIME_();             /* timestamp */
            QS_OBJ_(sender);        /* the sender object */
            QS_SIG_(e->sig);        /* the signal of the event */
            QS_OBJ_(me);            /* this active object (recipient) */
            QS_2U8_(e->poolId_, e->refCtr_); /* pool Id & ref Count */
            QS_EQC_((QEQueueCtr)nFree); /* # free entries available */
            QS_EQC_((QEQueueCtr)0); /* min # free entries (unknown) */
        QS_END_NOCRIT_()

        if (e->poolId_ != (uint8_t)0) { /* is it a pool event? */
            QF_EVT_REF_CTR_INC_(e); /* increment the reference counter */
        }
        /* posting to the embOS mailbox must succeed, see NOTE3 */
        Q_ALLEGE(OS_PutMailCond(&me->eQueue, (OS_CONST_PTR void *)&e)
                 == (char)0);

        status = true; /* return success */
    }
Exemplo n.º 7
0
//............................................................................
void QMsm::dispatch(QEvt const * const e) {
    QMState const *s = m_state.obj;                 // store the current state
    QMState const *t;
    QState r = Q_RET_HANDLED;
    QS_CRIT_STAT_

    Q_REQUIRE(s != (QMState const *)0);                 // must be initialized

    QS_BEGIN_(QS_QEP_DISPATCH, QS::priv_.smObjFilter, this)
        QS_TIME_();                                              // time stamp
        QS_SIG_(e->sig);                            // the signal of the event
        QS_OBJ_(this);                            // this state machine object
        QS_FUN_(s->stateHandler);                 // the current state handler
    QS_END_()

    for (t = s; t != static_cast<QMState const *>(0); t = t->parent) {
        r = (*t->stateHandler)(this, e);
        if (r != Q_RET_SUPER) {
            if (r == Q_RET_UNHANDLED) {           // unhandled due to a guard?

                QS_BEGIN_(QS_QEP_UNHANDLED, QS::priv_.smObjFilter, this)
                    QS_SIG_(e->sig);                // the signal of the event
                    QS_OBJ_(this);                // this state machine object
                    QS_FUN_(t->stateHandler);             // the current state
                QS_END_()
            }
            else {
                break;                 // event handled--break out of the loop
            }
        }
Exemplo n.º 8
0
/*..........................................................................*/
void QFsm_dispatch(QFsm *me, QEvent const *e) {
    QStateHandler s = me->state;                  /* save the current state */
    QS_INT_LOCK_KEY_
    QState r = (*s)(me, e);                       /* call the event handler */

    if (r == Q_RET_TRAN) {                             /* transition taken? */

        QS_BEGIN_(QS_QEP_TRAN, QS_smObj_, me)
            QS_TIME_();                                       /* time stamp */
            QS_SIG_(e->sig);                     /* the signal of the event */
            QS_OBJ_(me);                       /* this state machine object */
            QS_FUN_(s);                     /* the source of the transition */
            QS_FUN_(me->state);                     /* the new active state */
        QS_END_()

        (void)QEP_TRIG_(s, Q_EXIT_SIG);                 /* exit the source */
        (void)QEP_TRIG_(me->state, Q_ENTRY_SIG);        /* enter the target */
    }
    else {                                          /* transition not taken */
#ifdef Q_SPY
        if (r == Q_RET_HANDLED) {

            QS_BEGIN_(QS_QEP_INTERN_TRAN, QS_smObj_, me)
                QS_TIME_();                                   /* time stamp */
                QS_SIG_(e->sig);                 /* the signal of the event */
                QS_OBJ_(me);                   /* this state machine object */
                QS_FUN_(s);             /* the state that handled the event */
            QS_END_()
        }
        else {
Exemplo n.º 9
0
bool QMActive::post_(QEvt const * const e, uint_fast16_t const margin,
                    void const * const sender)
#endif
{
    uint_fast16_t nFree;
    bool status;
    QF_CRIT_STAT_

    QF_CRIT_ENTRY_();
    nFree = static_cast<uint_fast16_t>(m_eQueue.maxMsg - m_eQueue.nofMsg);

    if (nFree > margin) {
        QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_FIFO, QS::priv_.aoObjFilter, this)
            QS_TIME_();             // timestamp
            QS_OBJ_(sender);        // the sender object
            QS_SIG_(e->sig);        // the signal of the event
            QS_OBJ_(this);          // this active object (recipient)
            QS_2U8_(e->poolId_, e->refCtr_); // pool Id & ref Count
            QS_EQC_(static_cast<QEQueueCtr>(nFree)); // # free entries
            QS_EQC_(static_cast<QEQueueCtr>(0)); // min # free (unknown)
        QS_END_NOCRIT_()

        if (e->poolId_ != static_cast<uint8_t>(0)) { // is it a pool event?
            QF_EVT_REF_CTR_INC_(e); // increment the reference counter
        }

        // posting to the embOS mailbox must succeed, see NOTE3
        Q_ALLEGE_ID(710,
            OS_PutMailCond(&m_eQueue, static_cast<OS_CONST_PTR void *>(&e))
            == static_cast<char>(0));

        status = true; // return success
    }
Exemplo n.º 10
0
//............................................................................
// NOTE: disarm a time evt (no harm in disarming an already disarmed time evt)
uint8_t QTimeEvt::disarm(void) {
    uint8_t wasArmed;
    QF_INT_LOCK_KEY_
    QF_INT_LOCK_();
    if (m_prev != (QTimeEvt *)0) {        // is the time event actually armed?
        wasArmed = (uint8_t)1;
        if (this == QF_timeEvtListHead_) {
            QF_timeEvtListHead_ = m_next;
        }
        else {
            if (m_next != (QTimeEvt *)0) {        // not the last in the list?
                m_next->m_prev = m_prev;
            }
            m_prev->m_next = m_next;
        }
        m_prev = (QTimeEvt *)0;             // mark the time event as disarmed

        QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_DISARM, QS::teObj_, this)
            QS_TIME_();                                           // timestamp
            QS_OBJ_(this);                           // this time event object
            QS_OBJ_(m_act);                               // the active object
            QS_TEC_(m_ctr);                             // the number of ticks
            QS_TEC_(m_interval);                               // the interval
        QS_END_NOLOCK_()
    }
/*..........................................................................*/
uint8_t QTimeEvt_rearm(QTimeEvt * const me, QTimeEvtCtr const nTicks) {
    uint8_t isArmed;
    QF_CRIT_STAT_

    Q_REQUIRE((nTicks != (QTimeEvtCtr)0) /* cannot arm a timer with 0 ticks */
              && (me->act != (QActive *)0)   /* active object must be valid */
              && (me->super.sig >= (QSignal)Q_USER_SIG));   /* valid signal */

    QF_CRIT_ENTRY_();
    if (me->ctr == (QTimeEvtCtr)0) {           /* is the time evt disarmed? */
        isArmed = (uint8_t)0;
        if (QF_EVT_REF_CTR_(&me->super) == (uint8_t)0) {     /* not linked? */
            me->next = QF_timeEvtListHead_;
            QF_timeEvtListHead_ = me;
            QF_EVT_REF_CTR_INC_(&me->super);              /* mark as linked */
        }
    }
    else {                                       /* the time event is armed */
        isArmed = (uint8_t)1;
    }
    me->ctr = nTicks;       /* re-load the tick counter (shift the phasing) */

    QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_REARM, QS_teObj_, me)
        QS_TIME_();                                            /* timestamp */
        QS_OBJ_(me);                              /* this time event object */
        QS_OBJ_(me->act);                              /* the active object */
        QS_TEC_(me->ctr);                            /* the number of ticks */
        QS_TEC_(me->interval);                              /* the interval */
        QS_U8_(isArmed);                            /* was the timer armed? */
    QS_END_NOCRIT_()

    QF_CRIT_EXIT_();
    return isArmed;
}
Exemplo n.º 12
0
bool GuiQMActive::post_(QEvt const * const e, uint_fast16_t const /*margin*/,
                        void const * const sender)
#endif
{
    QF_CRIT_STAT_
    QF_CRIT_ENTRY_();

    QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_FIFO, QS::priv_.aoObjFilter, this)
        QS_TIME_();                  // timestamp
        QS_OBJ_(sender);             // the sender object
        QS_SIG_(e->sig);             // the signal of the event
        QS_OBJ_(this);               // this active object
        QS_2U8_(QF_EVT_POOL_ID_(e),  /* the poolID of the event */
                QF_EVT_REF_CTR_(e)); // the ref Ctr of the event
        QS_EQC_(0);                  // number of free entries (not used)
        QS_EQC_(0);                  // min number of free entries (not used)
    QS_END_NOCRIT_()

    // is it a dynamic event?
    if (QF_EVT_POOL_ID_(e) != static_cast<uint8_t>(0)) {
        QF_EVT_REF_CTR_INC_(e); // increment the reference counter
    }
    QF_CRIT_EXIT_();

    // QCoreApplication::postEvent() is thread-safe per Qt documentation
    QCoreApplication::postEvent(QApplication::instance(), new QP_Event(e));
    return true;
}
Exemplo n.º 13
0
/* NOTE: disarm a timer (no harm in disarming an already disarmed timer)    */
uint8_t QTimeEvt_disarm(QTimeEvt * const me) {
    uint8_t wasArmed;
    QF_CRIT_STAT_
    QF_CRIT_ENTRY_();
    if (me->ctr != (QTimeEvtCtr)0) {            /* is the time evt running? */
        wasArmed = (uint8_t)1;

        QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_DISARM, QS_priv_.teObjFilter, me)
            QS_TIME_();                                        /* timestamp */
            QS_OBJ_(me);                          /* this time event object */
            QS_OBJ_(me->act);                              /* the target AO */
            QS_TEC_(me->ctr);                        /* the number of ticks */
            QS_TEC_(me->interval);                          /* the interval */
            QS_U8_((uint8_t)(me->super.refCtr_ & (uint8_t)0x7F));/*tick rate*/
        QS_END_NOCRIT_()

        me->ctr = (QTimeEvtCtr)0;         /* schedule removal from the list */
    }
    else {                        /* the time event was already not running */
        wasArmed = (uint8_t)0;

        QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_DISARM_ATTEMPT,
                         QS_priv_.teObjFilter, me)
            QS_TIME_();                                        /* timestamp */
            QS_OBJ_(me);                          /* this time event object */
            QS_OBJ_(me->act);                              /* the target AO */
            QS_U8_((uint8_t)(me->super.refCtr_ & (uint8_t)0x7F));/*tick rate*/
        QS_END_NOCRIT_()

    }
    QF_CRIT_EXIT_();
    return wasArmed;
}
Exemplo n.º 14
0
/*..........................................................................*/
void QF_tick(void) {                                          /* see NOTE01 */
    QTimeEvt *t;
    QF_INT_LOCK_KEY_

    QF_INT_LOCK_();

    QS_BEGIN_NOLOCK_(QS_QF_TICK, (void *)0, (void *)0)
        QS_TEC_(++QS_tickCtr_);                         /* the tick counter */
    QS_END_NOLOCK_()

    t = QF_timeEvtListHead_;
    while (t != (QTimeEvt *)0) {
        --t->ctr;
        if (t->ctr == (QTimeEvtCtr)0) {     /* is time evt about to expire? */
            if (t->interval != (QTimeEvtCtr)0) { /* is it periodic timeout? */
                t->ctr = t->interval;               /* rearm the time event */
            }
            else { /* one-shot timeout, disarm by removing it from the list */
                if (t == QF_timeEvtListHead_) {
                    QF_timeEvtListHead_ = t->next;
                }
                else {
                    if (t->next != (QTimeEvt *)0) {  /* not the last event? */
                        t->next->prev = t->prev;
                    }
                    t->prev->next = t->next;
                }
                t->prev = (QTimeEvt *)0;         /* mark the event disarmed */

                QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_AUTO_DISARM, QS_teObj_, t)
                    QS_OBJ_(t);                   /* this time event object */
                    QS_OBJ_(t->act);                   /* the active object */
                QS_END_NOLOCK_()
            }

            QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_POST, QS_teObj_, t)
                QS_TIME_();                                    /* timestamp */
                QS_OBJ_(t);                        /* the time event object */
                QS_SIG_(t->super.sig);         /* signal of this time event */
                QS_OBJ_(t->act);                       /* the active object */
            QS_END_NOLOCK_()

            QF_INT_UNLOCK_();/* unlock interrupts before calling QF service */

               /* postFIFO() asserts internally that the event was accepted */
            QActive_postFIFO(t->act, (QEvent *)t);
        }
        else {
            static uint8_t volatile dummy;
            QF_INT_UNLOCK_();
            dummy = (uint8_t)0;   /* execute a few instructions, see NOTE02 */
        }

        QF_INT_LOCK_();        /* lock interrupts again to advance the link */
        t = t->next;
    }
Exemplo n.º 15
0
/**
* \description
* Arms a time event to fire in a specified number of clock ticks and with
* a specified interval. If the interval is zero, the time event is armed for
* one shot ('one-shot' time event). The time event gets directly posted
* (using the FIFO policy) into the event queue of the host active object.
*
* \arguments
* \arg[in,out] \c me     pointer (see \ref derivation)
* \arg[in]     \c nTicks number of clock ticks (at the associated rate)
*                        to rearm the time event with.
* \arg[in]     \c interval interval (in clock ticks) for periodic time event.
*
* \note After posting, a one-shot time event gets automatically disarmed
* while a periodic time event (interval != 0) is automatically re-armed.
*
* \note A time event can be disarmed at any time by calling the
* QTimeEvt_disarm() function. Also, a time event can be re-armed to fire
* in a different number of clock ticks by calling the QTimeEvt_rearm()
* function.
*
* \usage
* The following example shows how to arm a one-shot time event from a state
* machine of an active object:
* \include qf_state.c
*/
void QTimeEvt_armX(QTimeEvt * const me,
                   QTimeEvtCtr const nTicks, QTimeEvtCtr const interval)
{
    uint_fast8_t tickRate = (uint_fast8_t)me->super.refCtr_
                                & (uint_fast8_t)0x7F;
    QTimeEvtCtr ctr = me->ctr;
    QF_CRIT_STAT_

    /** \pre the host AO must be valid, time evnet must be disarmed,
    * number of clock ticks cannot be zero, and the signal must be valid.
    */
    Q_REQUIRE_ID(100, (me->act != (void *)0)
              && (ctr == (QTimeEvtCtr)0)
              && (nTicks != (QTimeEvtCtr)0)
              && (tickRate < (uint_fast8_t)QF_MAX_TICK_RATE)
              && (me->super.sig >= (QSignal)Q_USER_SIG));

    QF_CRIT_ENTRY_();
    me->ctr = nTicks;
    me->interval = interval;

    /* is the time event unlinked?
    * NOTE: For the duration of a single clock tick of the specified tick
    * rate a time event can be disarmed and yet still linked into the list,
    * because un-linking is performed exclusively in the QF_tickX() function.
    */
    if ((me->super.refCtr_ & (uint8_t)0x80) == (uint8_t)0) {
        me->super.refCtr_ |= (uint8_t)0x80;       /* mark as linked */

        /* The time event is initially inserted into the separate
        * "freshly armed" link list based on QF_timeEvtHead_[tickRate].act.
        * Only later, inside the QF_tickX() function, the "freshly armed"
        * list is appended to the main list of armed time events based on
        * QF_timeEvtHead_[tickRate].next. Again, this is to keep any
        * changes to the main list exclusively inside the QF_tickX()
        * function.
        */
        me->next = (QTimeEvt *)QF_timeEvtHead_[tickRate].act;
        QF_timeEvtHead_[tickRate].act = me;
    }

    QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_ARM, QS_priv_.teObjFilter, me)
        QS_TIME_();                /* timestamp */
        QS_OBJ_(me);               /* this time event object */
        QS_OBJ_(me->act);          /* the active object */
        QS_TEC_(nTicks);           /* the number of ticks */
        QS_TEC_(interval);         /* the interval */
        QS_U8_((uint8_t)tickRate); /* tick rate */
    QS_END_NOCRIT_()

    QF_CRIT_EXIT_();
}
Exemplo n.º 16
0
/*..........................................................................*/
void QHsm_init(QHsm *me, QEvent const *e) {
    QHsmState s;
                /* this state machine must be initialized with QHsm_ctor_() */
    Q_REQUIRE(((QFsm *)me)->state__.fsm != (QState)0);

    s = &QHsm_top;                        /* an HSM starts in the top state */
                                          /* trigger the initial transition */
    (*((QFsm *)me)->state__.fsm)((QFsm *)me, e);

    do {                                        /* drill into the target... */
        QHsmState path[QEP_MAX_NEST_DEPTH_];
        int8_t ip = (int8_t)0;               /* transition entry path index */
        QHsmState t = ((QFsm *)me)->state__.hsm;

        QS_BEGIN_(QS_QEP_STATE_INIT, QS_smObj_, me);
            QS_OBJ_(me);                       /* this state machine object */
            QS_FUN_(s);                                 /* the source state */
            QS_FUN_(((QFsm *)me)->state__.hsm);               /* the target */
        QS_END_();

        path[0] = t;
        for (t = QEP_TRIG_(t, QEP_EMPTY_SIG_); t != s;
             t = QEP_TRIG_(t, QEP_EMPTY_SIG_))
        {
            path[++ip] = t;
        }
                                            /* entry path must not overflow */
        Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_);

        do {        /* retrace the entry path in reverse (desired) order... */
                                                          /* enter path[ip] */
            if (QEP_TRIG_(path[ip], Q_ENTRY_SIG) == (QHsmState)0) {

                QS_BEGIN_(QS_QEP_STATE_ENTRY, QS_smObj_, me);
                    QS_OBJ_(me);               /* this state machine object */
                    QS_FUN_(path[ip]);                 /* the entered state */
                QS_END_();
            }
        } while (--ip >= (int8_t)0);

        s = ((QFsm *)me)->state__.hsm;
    } while (QEP_TRIG_(s, Q_INIT_SIG) == (QHsmState)0);

    QS_BEGIN_(QS_QEP_INIT_TRAN, QS_smObj_, me);
        QS_TIME_();                                           /* time stamp */
        QS_OBJ_(me);                           /* this state machine object */
        QS_FUN_(((QFsm *)me)->state__.hsm);         /* the new active state */
    QS_END_();
}
Exemplo n.º 17
0
/*..........................................................................*/
void QHsm_init(QHsm * const me, QEvt const * const e) {
    QStateHandler t = me->state.fun;
    QS_CRIT_STAT_

    Q_REQUIRE((me->vptr != (QMsmVtbl const *)0)    /* ctor must be executed */
              && (me->temp.fun != Q_STATE_CAST(0)) /* ctor must be executed */
              && (t == Q_STATE_CAST(&QHsm_top))); /*initial tran. NOT taken */

                           /* the top-most initial transition must be taken */
    Q_ALLEGE((*me->temp.fun)(me, e) == (QState)Q_RET_TRAN);

    do {                                        /* drill into the target... */
        QStateHandler path[QEP_MAX_NEST_DEPTH_];
        int_t ip = (int_t)0;                 /* transition entry path index */

        QS_BEGIN_(QS_QEP_STATE_INIT, QS_priv_.smObjFilter, me)
            QS_OBJ_(me);                       /* this state machine object */
            QS_FUN_(t);                                 /* the source state */
            QS_FUN_(me->temp.fun);  /* the target of the initial transition */
        QS_END_()

        path[0] = me->temp.fun;
        (void)QEP_TRIG_(me->temp.fun, QEP_EMPTY_SIG_);
        while (me->temp.fun != t) {
            ++ip;
            path[ip] = me->temp.fun;
            (void)QEP_TRIG_(me->temp.fun, QEP_EMPTY_SIG_);
        }
        me->temp.fun = path[0];
                                            /* entry path must not overflow */
        Q_ASSERT(ip < (int_t)QEP_MAX_NEST_DEPTH_);

        do {        /* retrace the entry path in reverse (desired) order... */
            QEP_ENTER_(path[ip]);                         /* enter path[ip] */
            --ip;
        } while (ip >= (int_t)0);

        t = path[0];                /* current state becomes the new source */
    } while (QEP_TRIG_(t, Q_INIT_SIG) == (QState)Q_RET_TRAN);

    QS_BEGIN_(QS_QEP_INIT_TRAN, QS_priv_.smObjFilter, me)
        QS_TIME_();                                           /* time stamp */
        QS_OBJ_(me);                           /* this state machine object */
        QS_FUN_(t);                                 /* the new active state */
    QS_END_()

    me->state.fun = t;                   /* change the current active state */
    me->temp.fun  = t;                  /* mark the configuration as stable */
}
Exemplo n.º 18
0
/*..........................................................................*/
QEvent const *QEQueue_get(QEQueue *me) {
    QEvent const *e;
    QF_CRIT_STAT_
    QF_CRIT_ENTRY_();
    if (me->frontEvt == (QEvent *)0) {               /* is the queue empty? */
        e = (QEvent *)0;                 /* no event available at this time */
    }
    else {                                        /* the queue is not empty */
        e = me->frontEvt;

        if (me->nFree != me->end) {       /* any events in the ring buffer? */
            me->frontEvt = QF_PTR_AT_(me->ring, me->tail); /* get from tail */
            if (me->tail == (QEQueueCtr)0) {      /* need to wrap the tail? */
                me->tail = me->end;                          /* wrap around */
            }
            --me->tail;

            ++me->nFree;          /* one more free event in the ring buffer */

            QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_GET, QS_eqObj_, me)
                QS_TIME_();                                    /* timestamp */
                QS_SIG_(e->sig);                /* the signal of this event */
                QS_OBJ_(me);                           /* this queue object */
                QS_U8_(QF_EVT_POOL_ID_(e));     /* the pool Id of the event */
                QS_U8_(QF_EVT_REF_CTR_(e));   /* the ref count of the event */
                QS_EQC_(me->nFree);               /* number of free entries */
            QS_END_NOCRIT_()
        }
        else {
Exemplo n.º 19
0
/*..........................................................................*/
QEvent const *QEQueue_get(QEQueue *me) {
    QEvent const *e;
    QF_INT_LOCK_KEY_
    QF_INT_LOCK_();
    if (me->frontEvt == (QEvent *)0) {               /* is the queue empty? */
        e = (QEvent const *)0;                 /* no event available at this time */
    }
    else {                                        /* the queue is not empty */
        e = me->frontEvt;

        if (me->nFree != me->end) {       /* any events in the ring buffer? */
            me->frontEvt = me->ring[me->tail];      /* remove from the tail */
            if (me->tail == (QEQueueCtr)0) {      /* need to wrap the tail? */
                me->tail = me->end;                          /* wrap around */
            }
            --me->tail;

            ++me->nFree;          /* one more free event in the ring buffer */

            QS_BEGIN_NOLOCK_(QS_QF_EQUEUE_GET, QS_eqObj_, me)
                QS_TIME_();                                    /* timestamp */
                QS_SIG_(e->sig);                /* the signal of this event */
                QS_OBJ_(me);                           /* this queue object */
                QS_U8_(e->dynamic_);  /* the dynamic attribute of the event */
                QS_EQC_(me->nFree);               /* number of free entries */
            QS_END_NOLOCK_()
        }
        else {
Exemplo n.º 20
0
/*..........................................................................*/
void QActive_unsubscribeAll(QActive const *me) {
    uint8_t p = me->prio;
    uint8_t i;
    QSignal sig;

    Q_REQUIRE(((uint8_t)0 < p) && (p <= (uint8_t)QF_MAX_ACTIVE)
              && (QF_active_[p] == me));

    i = QF_div8Lkup[p];
    for (sig = (QSignal)Q_USER_SIG; sig < QF_maxSignal_; ++sig) {
        QF_CRIT_STAT_
        QF_CRIT_ENTRY_();
        if ((QF_PTR_AT_(QF_subscrList_, sig).bits[i]
             & Q_ROM_BYTE(QF_pwr2Lkup[p])) != (uint8_t)0)
        {

            QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_UNSUBSCRIBE, QS_aoObj_, me)
                QS_TIME_();                                    /* timestamp */
                QS_SIG_(sig);                   /* the signal of this event */
                QS_OBJ_(me);                          /* this active object */
            QS_END_NOCRIT_()
                                                  /* clear the priority bit */
            QF_PTR_AT_(QF_subscrList_, sig).bits[i] &=
                Q_ROM_BYTE(QF_invPwr2Lkup[p]);
        }
        QF_CRIT_EXIT_();
    }
}
Exemplo n.º 21
0
/*..........................................................................*/
QEvent const *QActive_get_(QActive *me) {
    QEvent const *e;
    QF_INT_LOCK_KEY_
    QF_INT_LOCK_();

    QACTIVE_EQUEUE_WAIT_(me);          /* wait for event to arrive directly 
    ^#defined as: Q_ASSERT((me_)->eQueue.frontEvt != (QEvent *)0)  */
 
    e = me->eQueue.frontEvt;

    if (me->eQueue.nFree != me->eQueue.end) {  /* any events in the buffer? */
                                              /* remove event from the tail */
        me->eQueue.frontEvt = me->eQueue.ring[me->eQueue.tail];
        if (me->eQueue.tail == (QEQueueCtr)0) {   /* need to wrap the tail? */
            me->eQueue.tail = me->eQueue.end;                /* wrap around */
        }
        --me->eQueue.tail;

        ++me->eQueue.nFree;       /* one more free event in the ring buffer */

        QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_GET, QS_aoObj_, me)
            QS_TIME_();                                        /* timestamp */
            QS_SIG_(e->sig);                    /* the signal of this event */
            QS_OBJ_(me);                              /* this active object */
            QS_U8_(e->dynamic_);      /* the dynamic attribute of the event */
            QS_EQC_(me->eQueue.nFree);            /* number of free entries */
        QS_END_NOLOCK_()
    }
Exemplo n.º 22
0
/*..........................................................................*/
QEvt const *QActive_get_(QActive * const me) {
    QEQueueCtr nFree;
    QEvt const *e;
    QF_CRIT_STAT_
    QF_CRIT_ENTRY_();

    QACTIVE_EQUEUE_WAIT_(me);          /* wait for event to arrive directly */

    e = me->eQueue.frontEvt; /* always remove event from the front location */
    nFree= me->eQueue.nFree + (QEQueueCtr)1;       /* get volatile into tmp */
    me->eQueue.nFree = nFree;                   /* upate the number of free */

    if (nFree <= me->eQueue.end) {        /* any events in the ring buffer? */
                                              /* remove event from the tail */
        me->eQueue.frontEvt = QF_PTR_AT_(me->eQueue.ring, me->eQueue.tail);
        if (me->eQueue.tail == (QEQueueCtr)0) {   /* need to wrap the tail? */
            me->eQueue.tail = me->eQueue.end;                /* wrap around */
        }
        --me->eQueue.tail;

        QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_GET, QS_priv_.aoObjFilter, me)
            QS_TIME_();                                        /* timestamp */
            QS_SIG_(e->sig);                    /* the signal of this event */
            QS_OBJ_(me);                              /* this active object */
            QS_2U8_(e->poolId_, e->refCtr_);         /* pool Id & ref Count */
            QS_EQC_(nFree);                       /* number of free entries */
        QS_END_NOCRIT_()
    }
Exemplo n.º 23
0
QP_BEGIN_

//Q_DEFINE_THIS_MODULE("qeq_get")

//............................................................................
QEvt const *QEQueue::get(void) {
    QEvt const *e;
    QF_CRIT_STAT_

    QF_CRIT_ENTRY_();
    if (m_frontEvt == null_evt) {                       // is the queue empty?
        e = null_evt;                       // no event available at this time
    }
    else {
        e = m_frontEvt;

        if (m_nFree != m_end) {          // any events in the the ring buffer?
            m_frontEvt = QF_PTR_AT_(m_ring, m_tail);   // remove from the tail
            if (m_tail == static_cast<QEQueueCtr>(0)) {       // need to wrap?
                m_tail = m_end;                                 // wrap around
            }
            --m_tail;

            ++m_nFree;               // one more free event in the ring buffer

            QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_GET, QS::eqObj_, this)
                QS_TIME_();                                       // timestamp
                QS_SIG_(e->sig);                   // the signal of this event
                QS_OBJ_(this);                            // this queue object
                QS_U8_(QF_EVT_POOL_ID_(e));        // the pool Id of the event
                QS_U8_(QF_EVT_REF_CTR_(e));      // the ref count of the event
                QS_EQC_(m_nFree);                    // number of free entries
            QS_END_NOCRIT_()
        }
        else {
Exemplo n.º 24
0
//****************************************************************************
/// @description
/// 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.
///
/// @sa QP::QF::publish_(), QP::QMActive::subscribe(), and
/// QP::QMActive::unsubscribe()
///
void QMActive::unsubscribeAll(void) const {
    uint_fast8_t const p = m_prio;

    Q_REQUIRE_ID(500, (static_cast<uint_fast8_t>(0) < p)
                      && (p <= static_cast<uint_fast8_t>(QF_MAX_ACTIVE))
                      && (QF::active_[p] == this));

    uint_fast8_t const i =
        static_cast<uint_fast8_t>(QF_div8Lkup[p]);

    enum_t sig;
    for (sig = Q_USER_SIG; sig < QF_maxSignal_; ++sig) {
        QF_CRIT_STAT_
        QF_CRIT_ENTRY_();
        if ((QF_PTR_AT_(QF_subscrList_, sig).m_bits[i]
             & QF_pwr2Lkup[p]) != static_cast<uint8_t>(0))
        {

            QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_UNSUBSCRIBE,
                             QS::priv_.aoObjFilter, this)
                QS_TIME_();     // timestamp
                QS_SIG_(sig);   // the signal of this event
                QS_OBJ_(this);  // this active object
            QS_END_NOCRIT_()

            // clear the priority bit
            QF_PTR_AT_(QF_subscrList_, sig).m_bits[i] &= QF_invPwr2Lkup[p];
        }
        QF_CRIT_EXIT_();
    }
}
Exemplo n.º 25
0
//............................................................................
void QHsm::init(QEvent const *e) {
    QStateHandler t;
    QS_INT_LOCK_KEY_

                              // the top-most initial transition must be taken
    Q_ALLEGE((*m_state)(this, e) == Q_RET_TRAN);

    t = (QStateHandler)&QHsm::top;              // HSM starts in the top state
    do {                                           // drill into the target...
        QStateHandler path[QEP_MAX_NEST_DEPTH_];
        int8_t ip = (int8_t)0;                  // transition entry path index


        QS_BEGIN_(QS_QEP_STATE_INIT, QS::smObj_, this)
            QS_OBJ_(this);                        // this state machine object
            QS_FUN_(t);                                    // the source state
            QS_FUN_(m_state);          // the target of the initial transition
        QS_END_()

        path[0] = m_state;
        (void)QEP_TRIG_(m_state, QEP_EMPTY_SIG_);
        while (m_state != t) {
            ++ip;
            path[ip] = m_state;
            (void)QEP_TRIG_(m_state, QEP_EMPTY_SIG_);
        }
        m_state = path[0];
                                               // entry path must not overflow
        Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_);

        do {           // retrace the entry path in reverse (desired) order...
            QEP_ENTER_(path[ip]);                            // enter path[ip]
            --ip;
        } while (ip >= (int8_t)0);

        t = path[0];                   // current state becomes the new source
    } while (QEP_TRIG_(t, Q_INIT_SIG) == Q_RET_TRAN);
    m_state = t;

    QS_BEGIN_(QS_QEP_INIT_TRAN, QS::smObj_, this)
        QS_TIME_();                                              // time stamp
        QS_OBJ_(this);                            // this state machine object
        QS_FUN_(m_state);                              // the new active state
    QS_END_()
}
Exemplo n.º 26
0
void QActive_postFIFO(QActive *me, QEvent const *e) {
#else
void QActive_postFIFO(QActive *me, QEvent const *e, void const *sender) {
#endif

    QF_INT_LOCK_KEY_
    QF_INT_LOCK_();

    QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_POST_FIFO, QS_aoObj_, me)
        QS_TIME_();                                            /* timestamp */
        QS_OBJ_(sender);                               /* the sender object */
        QS_SIG_(e->sig);                         /* the signal of the event */
        QS_OBJ_(me);                      /* this active object (recipient) */
        QS_U8_(EVT_POOL_ID(e));                 /* the pool Id of the event */
        QS_U8_(EVT_REF_CTR(e));               /* the ref count of the event */
        QS_EQC_(me->eQueue.nFree);                /* number of free entries */
        QS_EQC_(me->eQueue.nMin);             /* min number of free entries */
    QS_END_NOLOCK_()

    if (EVT_POOL_ID(e) != (uint8_t)0) {              /* is it a pool event? */
        EVT_INC_REF_CTR(e);              /* increment the reference counter */
    }

    if (me->eQueue.frontEvt == (QEvent *)0) {               /* empty queue? */
        me->eQueue.frontEvt = e;                  /* deliver event directly */
        QACTIVE_EQUEUE_SIGNAL_(me);               /* signal the event queue */
    }
    else {         /* queue is not empty, insert event into the ring-buffer */
            /* the queue must be able to accept the event (cannot overflow) */
        Q_ASSERT(me->eQueue.nFree != (QEQueueCtr)0);
                                /* insert event into the ring buffer (FIFO) */
        me->eQueue.ring[me->eQueue.head] = e;
        if (me->eQueue.head == (QEQueueCtr)0) {   /* need to wrap the head? */
            me->eQueue.head = me->eQueue.end;                /* wrap around */
        }
        --me->eQueue.head;

        --me->eQueue.nFree;                 /* update number of free events */
        if (me->eQueue.nMin > me->eQueue.nFree) {
            me->eQueue.nMin = me->eQueue.nFree;        /* update min so far */
        }
    }
    QF_INT_UNLOCK_();
}
Exemplo n.º 27
0
void QF_publish_(QEvt const * const e, void const * const sender)
#endif
{
    QF_CRIT_STAT_

      /* make sure that the published signal is within the configured range */
    Q_REQUIRE(e->sig < (QSignal)QF_maxSignal_);

    QF_CRIT_ENTRY_();

    QS_BEGIN_NOCRIT_(QS_QF_PUBLISH, (void *)0, (void *)0)
        QS_TIME_();                                        /* the timestamp */
        QS_OBJ_(sender);                               /* the sender object */
        QS_SIG_(e->sig);                         /* the signal of the event */
        QS_2U8_(e->poolId_, e->refCtr_);/* pool Id & ref Count of the event */
    QS_END_NOCRIT_()

    if (e->poolId_ != (uint8_t)0) {               /* is it a dynamic event? */
        QF_EVT_REF_CTR_INC_(e);      /* increment reference counter, NOTE01 */
    }
    QF_CRIT_EXIT_();

#if (QF_MAX_ACTIVE <= 8)
    {
        uint8_t tmp = QF_subscrList_[e->sig].bits[0];
        while (tmp != (uint8_t)0) {
            uint8_t p = QF_LOG2(tmp);
            tmp &= Q_ROM_BYTE(QF_invPwr2Lkup[p]);   /* clear subscriber bit */
            Q_ASSERT(QF_active_[p] != (QActive *)0);  /* must be registered */

                /* QACTIVE_POST() asserts internally if the queue overflows */
            QACTIVE_POST(QF_active_[p], e, sender);
        }
    }
#else
    {
        uint_t i = (uint_t)Q_DIM(QF_subscrList_[0].bits);
        do {               /* go through all bytes in the subscription list */
            uint8_t tmp;
            --i;
            tmp = QF_PTR_AT_(QF_subscrList_, e->sig).bits[i];
            while (tmp != (uint8_t)0) {
                uint8_t p = QF_LOG2(tmp);
                tmp &= Q_ROM_BYTE(QF_invPwr2Lkup[p]);/*clear subscriber bit */
                p = (uint8_t)(p + (uint8_t)(i << 3));/* adjust the priority */
                Q_ASSERT(QF_active_[p] != (QActive *)0);/*must be registered*/

                /* QACTIVE_POST() asserts internally if the queue overflows */
                QACTIVE_POST(QF_active_[p], e, sender);
            }
        } while (i != (uint_t)0);
    }
#endif

    QF_gc(e);                      /* run the garbage collector, see NOTE01 */
}
Exemplo n.º 28
0
/*..........................................................................*/
QTimeEvtCtr QTimeEvt_ctr(QTimeEvt const * const me) {
    QTimeEvtCtr ret;
    QF_CRIT_STAT_

    QF_CRIT_ENTRY_();
    ret = me->ctr;

    QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_CTR, QS_priv_.teObjFilter, me)
        QS_TIME_();                                            /* timestamp */
        QS_OBJ_(me);                              /* this time event object */
        QS_OBJ_(me->act);                                  /* the target AO */
        QS_TEC_(ret);                                /* the current counter */
        QS_TEC_(me->interval);                              /* the interval */
        QS_U8_((uint8_t)(me->super.refCtr_ & (uint8_t)0x7F));  /* tick rate */
    QS_END_NOCRIT_()

    QF_CRIT_EXIT_();
    return ret;
}
Exemplo n.º 29
0
/*..........................................................................*/
QEvent const *QActive_get_(QActive *me) {
    QEvent const *e;
    QF_INT_LOCK_KEY_
    QF_INT_LOCK_();

    QACTIVE_OSOBJECT_WAIT_(me);        /* wait for event to arrive directly */

    e = me->eQueue__.frontEvt__;

    if (me->eQueue__.nUsed__ != (QEQueueCtr)0) {/*any events in the buffer? */
                                                    /* remove from the tail */
        me->eQueue__.frontEvt__ = me->eQueue__.ring__[me->eQueue__.tail__];
        ++me->eQueue__.tail__;
        if (me->eQueue__.tail__ == me->eQueue__.end__) {    /* wrap around? */
            me->eQueue__.tail__ = (QEQueueCtr)0;           /* wrap the tail */
        }

        --me->eQueue__.nUsed__;        /* one less event in the ring buffer */

        QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_GET, QS_aoObj_, me);
            QS_TIME_();                                        /* timestamp */
            QS_SIG_(e->sig);                    /* the signal of this event */
            QS_OBJ_(me);                              /* this active object */
            QS_U8_(e->attrQF__);           /* the QF attribute of the event */
            QS_EQC_(me->eQueue__.nUsed__);        /* number of used entries */
        QS_END_NOLOCK_();
    }
    else {
        me->eQueue__.frontEvt__ = (QEvent const *)0; /* queue becomes empty */
        QACTIVE_OSOBJECT_ONIDLE_(me);

        QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_GET_LAST, QS_aoObj_, me);
            QS_TIME_();                                        /* timestamp */
            QS_SIG_(e->sig);                    /* the signal of this event */
            QS_OBJ_(me);                              /* this active object */
            QS_U8_(e->attrQF__);           /* the QF attribute of the event */
        QS_END_NOLOCK_();
    }
    QF_INT_UNLOCK_();
    return e;
}
Exemplo n.º 30
0
/*..........................................................................*/
void QS_obj_dict(void const * const obj,
                 char_t const Q_ROM * const name)
{
    QS_CRIT_STAT_
    QS_CRIT_ENTRY_();
    QS_beginRec((uint8_t)QS_OBJ_DICT);
    QS_OBJ_(obj);
    QS_STR_ROM_(name);
    QS_endRec();
    QS_CRIT_EXIT_();
    QS_onFlush();
}