//**************************************************************************** /// @description /// QP::QF::run() is typically called from your startup code after you /// initialize the QF and start at least one active object or "naked" thread /// (with QP::QMActive::start() or QP::QXThread::start(), respectively). /// /// @returns QP::QF::run() typically does not return in embedded applications. /// However, when QP runs on top of an operating system, QP::QF::run() might /// return and in this case the return represents the error code (0 for /// success). Typically the value returned from QP::QF::run() is subsequently /// passed on as return from main(). /// int_t QF::run(void) { /// @pre QXK_init() must be called __before__ QP::QF::run() to initialize /// the QXK idle thread. Q_REQUIRE_ID(100, active_[0] == &l_idleThread); // switch to the highest-priority task QF_INT_DISABLE(); QXK_attr_.curr = &l_idleThread; // mark QXK as running uint_fast8_t p = QXK_attr_.readySet.findMax(); // next priority to run QXK_attr_.next = active_[p]; QXK_start_(); // start QXK multitasking (NOTE: enables interrupts) /* the QXK start should not return, but just in case... */ Q_ERROR_ID(110); return static_cast<int_t>(0); }
bool QXThread::post_(QEvt const * const e, uint_fast16_t const margin, void const * const sender) #endif { bool stat; QF_CRIT_STAT_ // is it the private time event? if (e == &m_timeEvt) { QF_CRIT_ENTRY_(); stat = true; // the private time event is disarmed and not in any queue, // so it is safe to change its signal. The signal of 0 means // that the time event __has__ expired. m_timeEvt.sig = static_cast<QSignal>(0); unblock(); QF_CRIT_EXIT_(); } // is the event queue provided? else if (m_eQueue.m_end != static_cast<QEQueueCtr>(0)) { QF_CRIT_ENTRY_(); (void)teDisarm_(); QF_CRIT_EXIT_(); #ifndef Q_SPY stat = QMActive::post_(e, margin); #else stat = QMActive::post_(e, margin, sender); #endif } else { // the queue is not available QF::gc(e); // make sure the event is not leaked stat = false; Q_ERROR_ID(410); } return stat; }
/* This function is called when RTX detects a runtime error. * Parameter 'error_code' holds the runtime error code. */ void os_error(uint32_t err_code); /* prototype */ void os_error(uint32_t error_code) { /* perform customized error handling... */ GPIOF->DATA_Bits[LED_RED] = 0xFFU; /* turn LED on */ Q_ERROR_ID(error_code); /* NOTE: does not return */ }
//............................................................................ int_t QF::run(void) { onStartup(); // QF callback to configure and start interrupts OS_Start(); // start embOS multitasking Q_ERROR_ID(100); // OS_Start() should never return return static_cast<int_t>(0); // dummy return to make the compiler happy }
/*..........................................................................*/ int_t QF_run(void) { QF_onStartup(); /* QF callback to configure and start interrupts */ OS_Start(); /* start embOS multitasking */ Q_ERROR_ID(100); /* OS_Start() should never return */ return (int_t)0; /* dummy return to make the compiler happy */ }
/** * @description * Dispatches an event for processing to a meta state machine (MSM). * The processing of an event represents one run-to-completion (RTC) step. * * @param[in,out] me pointer (see @ref oop) * @param[in] e pointer to the event to be dispatched to the MSM * * @note * This function should be called only via the virtual table (see * QMSM_DISPATCH()) and should NOT be called directly in the applications. */ void QMsm_dispatch_(QMsm * const me, QEvt const * const e) { QMState const *s = me->state.obj; /* store the current state */ QMState const *t = s; QState r = (QState)Q_RET_SUPER; QS_CRIT_STAT_ /** @pre current state must be initialized */ Q_REQUIRE_ID(300, s != (QMState const *)0); QS_BEGIN_(QS_QEP_DISPATCH, QS_priv_.smObjFilter, me) QS_TIME_(); /* time stamp */ QS_SIG_(e->sig); /* the signal of the event */ QS_OBJ_(me); /* this state machine object */ QS_FUN_(s->stateHandler); /* the current state handler */ QS_END_() /* scan the state hierarchy up to the top state... */ do { r = (*t->stateHandler)(me, e); /* call state handler function */ /* event handled? (the most frequent case) */ if (r >= (QState)Q_RET_HANDLED) { break; /* done scanning the state hierarchy */ } /* event unhandled and passed to the superstate? */ else if (r == (QState)Q_RET_SUPER) { t = t->superstate; /* advance to the superstate */ } /* event unhandled and passed to a submachine superstate? */ else if (r == (QState)Q_RET_SUPER_SUB) { t = me->temp.obj; /* current host state of the submachie */ } /* event unhandled due to a guard? */ else if (r == (QState)Q_RET_UNHANDLED) { QS_BEGIN_(QS_QEP_UNHANDLED, QS_priv_.smObjFilter, me) QS_SIG_(e->sig); /* the signal of the event */ QS_OBJ_(me); /* this state machine object */ QS_FUN_(t->stateHandler); /* the current state */ QS_END_() t = t->superstate; /* advance to the superstate */ } else { /* no other return value should be produced */ Q_ERROR_ID(310); } } while (t != (QMState const *)0); /* any kind of transition taken? */ if (r >= (QState)Q_RET_TRAN) { #ifdef Q_SPY QMState const *ts = t; /* transition source for QS tracing */ /* the transition source state must not be NULL */ Q_ASSERT_ID(320, ts != (QMState const *)0); #endif /* Q_SPY*/ do { /* save the transition-action table before it gets clobbered */ QMTranActTable const *tatbl = me->temp.tatbl; /* was a regular state transition segment taken? */ if (r == (QState)Q_RET_TRAN) { QMsm_exitToTranSource_(me, s, t); r = QMsm_execTatbl_(me, tatbl); } /* was an initial transition segment taken? */ else if (r == (QState)Q_RET_TRAN_INIT) { r = QMsm_execTatbl_(me, tatbl); } /* was a transition segment to history taken? */ else if (r == (QState)Q_RET_TRAN_HIST) { QMState const *hist = me->state.obj; /* save history */ me->state.obj = s; /* restore the original state */ QMsm_exitToTranSource_(me, s, t); (void)QMsm_execTatbl_(me, tatbl); r = QMsm_enterHistory_(me, hist); } /* was a transition segment to an entry point taken? */ else if (r == (QState)Q_RET_TRAN_EP) { r = QMsm_execTatbl_(me, tatbl); } /* was a transition segment to an exit point taken? */ else if (r == (QState)Q_RET_TRAN_XP) { QActionHandler const act = me->state.act; /* save XP action */ me->state.obj = s; /* restore the original state */ r = (*act)(me); /* execute the XP action */ if (r == (QState)Q_RET_TRAN) { QMsm_exitToTranSource_(me, s, t); /* take the tran-to-XP segment inside submachine */ (void)QMsm_execTatbl_(me, tatbl); me->state.obj = s; /* restore original state (history) */ #ifdef Q_SPY t = me->temp.tatbl->target; /* store for tracing */ #endif /* Q_SPY */ /* take the XP-Segment from submachine-state */ r = QMsm_execTatbl_(me, me->temp.tatbl); QS_BEGIN_(QS_QEP_TRAN_XP, QS_priv_.smObjFilter, me) QS_OBJ_(me); /* this state machine object */ QS_FUN_(s); /* source handler */ QS_FUN_(t); /* target handler */ QS_END_() } }
//**************************************************************************** void QXThread::dispatch(QEvt const * const /*e*/) { Q_ERROR_ID(200); }
//**************************************************************************** // QXThread virtual function implementations... void QXThread::init(QEvt const * const /*e*/) { Q_ERROR_ID(100); }
//**************************************************************************** void QXThread::postLIFO(QEvt const * const /*e*/) { Q_ERROR_ID(510); }