Linux Face / QPFramework
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers qvanilla.cpp Source File

qvanilla.cpp

Go to the documentation of this file.
00001 //////////////////////////////////////////////////////////////////////////////
00002 // Product: QF/C++
00003 // Last Updated for Version: 4.0.00
00004 // Date of the Last Update:  Apr 07, 2008
00005 //
00006 //                    Q u a n t u m     L e a P s
00007 //                    ---------------------------
00008 //                    innovating embedded systems
00009 //
00010 // Copyright (C) 2002-2008 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
00027 //////////////////////////////////////////////////////////////////////////////
00028 #include "qf_pkg.h"
00029 #include "qassert.h"
00030 
00031 Q_DEFINE_THIS_MODULE(qvanilla)
00032 
00033 /// \file
00034 /// \ingroup qf
00035 /// \brief "vanilla" cooperative kernel,
00036 /// QActive::start(), QActive::stop(), and QF::run() implementation.
00037 
00038 // Package-scope objects -----------------------------------------------------
00039 #if (QF_MAX_ACTIVE <= 8)
00040     QPSet8  volatile QF_readySet_;           // QF-ready set of active objects
00041 #else
00042     QPSet64 volatile QF_readySet_;           // QF-ready set of active objects
00043 #endif
00044 
00045 //............................................................................
00046 char const Q_ROM * Q_ROM_VAR QF::getPortVersion(void) {
00047     static const char Q_ROM version[] = "4.0.00";
00048     return version;
00049 }
00050 //............................................................................
00051 void QF::init(void) {
00052     // nothing to do for the "vanilla" kernel
00053 }
00054 //............................................................................
00055 void QF::stop(void) {
00056     QF::onCleanup();                                       // cleanup callback
00057     // nothing else to do for the "vanilla" kernel
00058 }
00059 //............................................................................
00060 void QF::run(void) {
00061     QF::onStartup();                                       // startup callback
00062 
00063     for (;;) {                                           // the bacground loop
00064         QF_INT_LOCK_KEY_
00065         QF_INT_LOCK_();
00066         if (QF_readySet_.notEmpty()) {
00067             uint8_t p = QF_readySet_.findMax();
00068             QActive *a = active_[p];
00069             QF_INT_UNLOCK_();
00070 
00071             QEvent const *e = a->get_();     // get the next event for this AO
00072             a->dispatch(e);                         // dispatch evt to the HSM
00073             gc(e);       // determine if event is garbage and collect it if so
00074         }
00075         else {
00076 #ifndef QF_INT_KEY_TYPE
00077             QF::onIdle();                                        // see NOTE01
00078 #else
00079             QF::onIdle(intLockKey_);                             // see NOTE01
00080 #endif                                                      // QF_INT_KEY_TYPE
00081         }
00082     }
00083 }
00084 //............................................................................
00085 void QActive::start(uint8_t prio,
00086                     QEvent const *qSto[], uint32_t qLen,
00087                     void *stkSto, uint32_t /*lint -e1904 stkSize */,
00088                     QEvent const *ie)
00089 {
00090     Q_REQUIRE(((uint8_t)0 < prio) && (prio <= (uint8_t)QF_MAX_ACTIVE)
00091               && (stkSto == (void *)0));      // does not need per-actor stack
00092 
00093     m_eQueue.init(qSto, (QEQueueCtr)qLen);               // initialize QEQueue
00094     m_prio = prio;                // set the QF priority of this active object
00095     QF::add_(this);                     // make QF aware of this active object
00096     init(ie);                                    // execute initial transition
00097 
00098     QS_FLUSH();                          // flush the trace buffer to the host
00099 }
00100 //............................................................................
00101 void QActive::stop(void) {
00102     QF::remove_(this);
00103 }
00104 
00105 //////////////////////////////////////////////////////////////////////////////
00106 // NOTE01:
00107 // QF::onIdle() must be called with interrupts LOCKED because the
00108 // determination of the idle condition (no events in the queues) can change
00109 // at any time by an interrupt posting events to a queue. The QF::onIdle()
00110 // MUST enable interrups internally, perhaps at the same time as putting the
00111 // CPU into a power-saving mode.
00112 //
00113