|
QP/C++
|
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
1.7.5.1