QP/C++
qvanilla.cpp
Go to the documentation of this file.
00001 
00002 // Product: QF/C++
00003 // Last Updated for Version: 4.3.00
00004 // Date of the Last Update:  Nov 01, 2011
00005 //
00006 //                    Q u a n t u m     L e a P s
00007 //                    ---------------------------
00008 //                    innovating embedded systems
00009 //
00010 // Copyright (C) 2002-2011 Quantum Leaps, LLC. All rights reserved.
00011 //
00012 // This software may be distributed and modified under the terms of the GNU
00013 // General Public License version 2 (GPL) as published by the Free Software
00014 // Foundation and appearing in the file GPL.TXT included in the packaging of
00015 // this file. Please note that GPL Section 2[b] requires that all works based
00016 // on this software must also be made publicly available under the terms of
00017 // the GPL ("Copyleft").
00018 //
00019 // Alternatively, this software may be distributed and modified under the
00020 // terms of Quantum Leaps commercial licenses, which expressly supersede
00021 // the GPL and are specifically designed for licensees interested in
00022 // retaining the proprietary status of their code.
00023 //
00024 // Contact information:
00025 // Quantum Leaps Web site:  http://www.quantum-leaps.com
00026 // e-mail:                  info@quantum-leaps.com
00028 #include "qf_pkg.h"
00029 #include "qassert.h"
00030 
00035 
00036 #ifdef Q_USE_NAMESPACE
00037 namespace QP {
00038 #endif
00039 
00040 Q_DEFINE_THIS_MODULE(qvanilla)
00041 
00042 // Package-scope objects -----------------------------------------------------
00043 extern "C" {
00044 #if (QF_MAX_ACTIVE <= 8)
00045     QPSet8  volatile QF_readySet_;              // ready set of active objects
00046 #else
00047     QPSet64 volatile QF_readySet_;              // ready set of active objects
00048 #endif
00049 
00050 uint8_t volatile QF_currPrio_;            
00051 uint8_t volatile QF_intNest_;                     
00052 
00053 }                                                                // extern "C"
00054 
00055 //............................................................................
00056 char const Q_ROM * Q_ROM_VAR QF::getPortVersion(void) {
00057     static const char Q_ROM version[] = "4.3.00";
00058     return version;
00059 }
00060 //............................................................................
00061 void QF::init(void) {
00062     // nothing to do for the "vanilla" kernel
00063 }
00064 //............................................................................
00065 void QF::stop(void) {
00066     QF::onCleanup();                                       // cleanup callback
00067     // nothing else to do for the "vanilla" kernel
00068 }
00069 //............................................................................
00070 void QF::run(void) {
00071     QF::onStartup();                                       // startup callback
00072 
00073     for (;;) {                                           // the bacground loop
00074         QF_INT_DISABLE();
00075         if (QF_readySet_.notEmpty()) {
00076             uint8_t p = QF_readySet_.findMax();
00077             QActive *a = active_[p];
00078             QF_currPrio_ = p;                     // save the current priority
00079             QF_INT_ENABLE();
00080 
00081             QEvent const *e = a->get_();     // get the next event for this AO
00082             a->dispatch(e);                         // dispatch evt to the HSM
00083             gc(e);       // determine if event is garbage and collect it if so
00084         }
00085         else {
00086             QF::onIdle();                                        // see NOTE01
00087         }
00088     }
00089 }
00090 //............................................................................
00091 void QActive::start(uint8_t prio,
00092                     QEvent const *qSto[], uint32_t qLen,
00093                     void *stkSto, uint32_t /*lint -e1904 stkSize */,
00094                     QEvent const *ie)
00095 {
00096     Q_REQUIRE(((uint8_t)0 < prio) && (prio <= (uint8_t)QF_MAX_ACTIVE)
00097               && (stkSto == (void *)0));      // does not need per-actor stack
00098 
00099     m_eQueue.init(qSto, (QEQueueCtr)qLen);               // initialize QEQueue
00100     m_prio = prio;                // set the QF priority of this active object
00101     QF::add_(this);                     // make QF aware of this active object
00102     init(ie);                                    // execute initial transition
00103 
00104     QS_FLUSH();                          // flush the trace buffer to the host
00105 }
00106 //............................................................................
00107 void QActive::stop(void) {
00108     QF::remove_(this);
00109 }
00110 
00111 #ifdef Q_USE_NAMESPACE
00112 }                                                              // namespace QP
00113 #endif
00114 
00116 // NOTE01:
00117 // QF::onIdle() must be called with interrupts DISABLED because the
00118 // determination of the idle condition (no events in the queues) can change
00119 // at any time by an interrupt posting events to a queue. The QF::onIdle()
00120 // MUST enable interrups internally, perhaps at the same time as putting the
00121 // CPU into a power-saving mode.
00122 //
00123