QP/C++
qk.cpp
Go to the documentation of this file.
00001 
00002 // Product: QK/C++
00003 // Last Updated for Version: 4.5.00
00004 // Date of the Last Update:  May 19, 2012
00005 //
00006 //                    Q u a n t u m     L e a P s
00007 //                    ---------------------------
00008 //                    innovating embedded systems
00009 //
00010 // Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved.
00011 //
00012 // This program is open source software: you can redistribute it and/or
00013 // modify it under the terms of the GNU General Public License as published
00014 // by the Free Software Foundation, either version 2 of the License, or
00015 // (at your option) any later version.
00016 //
00017 // Alternatively, this program may be distributed and modified under the
00018 // terms of Quantum Leaps commercial licenses, which expressly supersede
00019 // the GNU General Public License and are specifically designed for
00020 // licensees interested in retaining the proprietary status of their code.
00021 //
00022 // This program is distributed in the hope that it will be useful,
00023 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00024 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00025 // GNU General Public License for more details.
00026 //
00027 // You should have received a copy of the GNU General Public License
00028 // along with this program. If not, see <http://www.gnu.org/licenses/>.
00029 //
00030 // Contact information:
00031 // Quantum Leaps Web sites: http://www.quantum-leaps.com
00032 //                          http://www.state-machine.com
00033 // e-mail:                  info@quantum-leaps.com
00035 #include "qk_pkg.h"
00036 #include "qassert.h"
00037 
00043 
00044 // Public-scope objects ------------------------------------------------------
00045 extern "C" {
00046 #if (QF_MAX_ACTIVE <= 8)
00047     QP_ QPSet8  QK_readySet_;                               // ready set of QK
00048 #else
00049     QP_ QPSet64 QK_readySet_;                               // ready set of QK
00050 #endif
00051                                          // start with the QK scheduler locked
00052 uint8_t QK_currPrio_ = static_cast<uint8_t>(QF_MAX_ACTIVE + 1);
00053 uint8_t QK_intNest_;                          // start with nesting level of 0
00054 
00055 }                                                                // extern "C"
00056 
00057 QP_BEGIN_
00058 
00059 Q_DEFINE_THIS_MODULE("qk")
00060 
00061 //............................................................................
00062 char_t const Q_ROM * Q_ROM_VAR QK::getVersion(void) {
00063     uint8_t const u8_zero = static_cast<uint8_t>('0');
00064     static char_t const Q_ROM Q_ROM_VAR version[] = {
00065         static_cast<char_t>(((QP_VERSION >> 12) & 0xFU) + u8_zero),
00066         static_cast<char_t>('.'),
00067         static_cast<char_t>(((QP_VERSION >>  8) & 0xFU) + u8_zero),
00068         static_cast<char_t>('.'),
00069         static_cast<char_t>(((QP_VERSION >>  4) & 0xFU) + u8_zero),
00070         static_cast<char_t>((QP_VERSION         & 0xFU) + u8_zero),
00071         static_cast<char_t>('\0')
00072     };
00073     return version;
00074 }
00075 //............................................................................
00076 void QF::init(void) {
00077     QK_init();           // QK initialization ("C" linkage, might be assembly)
00078 }
00079 //............................................................................
00080 void QF::stop(void) {
00081     QF::onCleanup();                                       // cleanup callback
00082     // nothing else to do for the QK preemptive kernel
00083 }
00084 //............................................................................
00085 static void initialize(void) {
00086     QK_currPrio_ = static_cast<uint8_t>(0);   // priority for the QK idle loop
00087     uint8_t p = QK_schedPrio_();
00088     if (p != static_cast<uint8_t>(0)) {
00089         QK_sched_(p);                    // process all events produced so far
00090     }
00091 }
00092 //............................................................................
00093 int16_t QF::run(void) {
00094     QF_INT_DISABLE();
00095     initialize();
00096     onStartup();                                           // startup callback
00097     QF_INT_ENABLE();
00098 
00099     for (;;) {                                             // the QK idle loop
00100         QK::onIdle();                        // invoke the QK on-idle callback
00101     }
00102                       // this unreachable return is to make the compiler happy
00103     return static_cast<int16_t>(0);
00104 }
00105 //............................................................................
00106 void QActive::start(uint8_t const prio,
00107                    QEvt const *qSto[], uint32_t const qLen,
00108                    void * const stkSto, uint32_t const stkSize,
00109                    QEvt const * const ie)
00110 {
00111     Q_REQUIRE((static_cast<uint8_t>(0) < prio)
00112               && (prio <= static_cast<uint8_t>(QF_MAX_ACTIVE)));
00113 
00114     m_eQueue.init(qSto, static_cast<QEQueueCtr>(qLen));    // initialize queue
00115     m_prio = prio;
00116     QF::add_(this);                     // make QF aware of this active object
00117 
00118 #if defined(QK_TLS) || defined(QK_EXT_SAVE)
00119     // in the QK port the parameter stkSize is used as the thread flags
00120     m_osObject = static_cast<uint8_t>(stkSize);   // m_osObject contains flags
00121 
00122     // in the QK port the parameter stkSto is used as the thread-local-storage
00123     m_thread   = stkSto;   // contains the pointer to the thread-local-storage
00124 #else
00125     Q_ASSERT((stkSto == static_cast<void *>(0))
00126              && (stkSize == static_cast<uint32_t>(0)));
00127 #endif
00128 
00129     init(ie);                                    // execute initial transition
00130 
00131     QS_FLUSH();                          // flush the trace buffer to the host
00132 }
00133 //............................................................................
00134 void QActive::stop(void) {
00135     QF::remove_(this);                // remove this active object from the QF
00136 }
00137 
00138 QP_END_